<!DOCTYPE html>
<html>

<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
	<meta name="theme-color" content="#33474d">
	<title>失落的乐章</title>
	<link rel="stylesheet" href="/css/style.css" />
	
      <link rel="alternate" href="/atom.xml" title="失落的乐章" type="application/atom+xml">
    
</head>

<body>

	<header class="header">
		<nav class="header__nav">
			
				<a href="/archives" class="header__link">Archive</a>
			
				<a href="/tags" class="header__link">Tags</a>
			
				<a href="/atom.xml" class="header__link">RSS</a>
			
		</nav>
		<h1 class="header__title"><a href="/">失落的乐章</a></h1>
		<h2 class="header__subtitle">技术面前，永远都是学生。</h2>
	</header>

	<main>
		



	<article>
	
		<h1><a href="/2017/10/12/正则表达式/6. 正则表达式-示例/">正则表达式-示例</a></h1>
	
	<div class="article__infos">
		<span class="article__date">2017-10-12</span><br />
		
		
			<span class="article__tags">
			  	<a class="article__tag-link" href="/tags/正则表达式/">正则表达式</a>
			</span>
		
	</div>

	

	
		<h2 id="简单表达式"><a href="#简单表达式" class="headerlink" title="简单表达式"></a>简单表达式</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;正则表达式的最简单形式是在搜索字符串中匹配其本身的单个普通字符。例如，单字符模式，如 A，不论出现在搜索字符串中的何处，它总是匹配字母 A。下面是一些单字符正则表达式模式的示例：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">/a/</div><div class="line">/7/</div><div class="line">/M/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;可以将许多单字符组合起来以形成大的表达式。例如，以下正则表达式组合了单字符表达式：a、7 和 M。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/a7M/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;请注意，没有串联运算符。只须在一个字符后面键入另一个字符。</p>
<h2 id="字符匹配"><a href="#字符匹配" class="headerlink" title="字符匹配"></a>字符匹配</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;句点 (.) 匹配字符串中的各种打印或非打印字符，只有一个字符例外。这个例外就是换行符 (\n)。下面的正则表达式匹配 aac、abc、acc、adc 等等，以及 a1c、a2c、a-c 和 a#c：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/a.c/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;若要匹配包含文件名的字符串，而句点 (.) 是输入字符串的组成部分，请在正则表达式中的句点前面加反斜扛 (\) 字符。举例来说明，下面的正则表达式匹配 filename.ext：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/filename\.ext/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;这些表达式只让您匹配”任何”单个字符。可能需要匹配列表中的特定字符组。例如，可能需要查找用数字表示的章节标题（Chapter 1、Chapter 2 等等）。</p>
<h2 id="中括号表达式"><a href="#中括号表达式" class="headerlink" title="中括号表达式"></a>中括号表达式</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;若要创建匹配字符组的一个列表，请在方括号（[ 和 ]）内放置一个或更多单个字符。当字符括在中括号内时，该列表称为”中括号表达式”。与在任何别的位置一样，普通字符在中括号内表示其本身，即，它在输入文本中匹配一次其本身。大多数特殊字符在中括号表达式内出现时失去它们的意义。不过也有一些例外，如：</p>
<ul>
<li>如果 ] 字符不是第一项，它结束一个列表。若要匹配列表中的 ] 字符，请将它放在第一位，紧跟在开始 [ 后面。</li>
<li>\ 字符继续作为转义符。若要匹配 \ 字符，请使用 \\。</li>
</ul>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;括在中括号表达式中的字符只匹配处于正则表达式中该位置的单个字符。以下正则表达式匹配 Chapter 1、Chapter 2、Chapter 3、Chapter 4 和 Chapter 5：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/Chapter [12345]/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;请注意，单词 Chapter 和后面的空格的位置相对于中括号内的字符是固定的。中括号表达式指定的只是匹配紧跟在单词 Chapter 和空格后面的单个字符位置的字符集。这是第九个字符位置。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;若要使用范围代替字符本身来表示匹配字符组，请使用连字符 (-) 将范围中的开始字符和结束字符分开。单个字符的字符值确定范围内的相对顺序。下面的正则表达式包含范围表达式，该范围表达式等效于上面显示的中括号中的列表。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/Chapter [1-5]/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;当以这种方式指定范围时，开始值和结束值两者都包括在范围内。注意，还有一点很重要，按 Unicode 排序顺序，开始值必须在结束值的前面。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;若要在中括号表达式中包括连字符，请采用下列方法之一：</p>
<ul>
<li>用反斜扛将它转义：</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">[\-]</div></pre></td></tr></table></figure>
<ul>
<li>将连字符放在中括号列表的开始或结尾。下面的表达式匹配所有小写字母和连字符：</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">[-a-z]</div><div class="line">[a-z-]</div></pre></td></tr></table></figure>
<ul>
<li>创建一个范围，在该范围中，开始字符值小于连字符，而结束字符值等于或大于连字符。下面的两个正则表达式都满足这一要求：</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">[!--]</div><div class="line">[!-~]</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;若要查找不在列表或范围内的所有字符，请将插入符号 (^) 放在列表的开头。如果插入字符出现在列表中的其他任何位置，则它匹配其本身。下面的正则表达式匹配1、2、3、4 或 5 之外的任何数字和字符：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/Chapter [^12345]/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;在上面的示例中，表达式在第九个位置匹配 1、2、3、4 或 5 之外的任何数字和字符。这样，例如，Chapter 7 就是一个匹配项，Chapter 9 也是一个匹配项。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;上面的表达式可以使用连字符 (-) 来表示：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/Chapter [^1-5]/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;中括号表达式的典型用途是指定任何大写或小写字母或任何数字的匹配。下面的表达式指定这样的匹配：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/[A-Za-z0-9]/</div></pre></td></tr></table></figure>
<h2 id="替换和分组"><a href="#替换和分组" class="headerlink" title="替换和分组"></a>替换和分组</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;替换使用 | 字符来允许在两个或多个替换选项之间进行选择。例如，可以扩展章节标题正则表达式，以返回比章标题范围更广的匹配项。但是，这并不象您可能认为的那样简单。替换匹配 | 字符任一侧最大的表达式。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;可能认为，下面的表达式匹配出现在行首和行尾、后面跟一个或两个数字的 Chapter 或 Section：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/^Chapter|Section [1-9][0-9]&#123;0,1&#125;$/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;很遗憾，上面的正则表达式要么匹配行首的单词 Chapter，要么匹配行尾的单词 Section 及跟在其后的任何数字。如果输入字符串是 Chapter 22，那么上面的表达式只匹配单词 Chapter。如果输入字符串是 Section 22，那么该表达式匹配 Section 22。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;若要使正则表达式更易于控制，可以使用括号来限制替换的范围，即，确保它只应用于两个单词 Chapter 和 Section。但是，括号也用于创建子表达式，并可能捕获它们以供以后使用，这一点在有关反向引用的那一节讲述。通过在上面的正则表达式的适当位置添加括号，就可以使该正则表达式匹配 Chapter 1 或 Section 3。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;下面的正则表达式使用括号来组合 Chapter 和 Section，以便表达式正确地起作用：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/^(Chapter|Section) [1-9][0-9]&#123;0,1&#125;$/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;尽管这些表达式正常工作，但 Chapter|Section 周围的括号还将捕获两个匹配字中的任一个供以后使用。由于在上面的表达式中只有一组括号，因此，只有一个被捕获的”子匹配项”。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;在上面的示例中，您只需要使用括号来组合单词 Chapter 和 Section 之间的选择。若要防止匹配被保存以备将来使用，请在括号内正则表达式模式之前放置 ?:。下面的修改提供相同的能力而不保存子匹配项：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/^(?:Chapter|Section) [1-9][0-9]&#123;0,1&#125;$/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;除 ?: 元字符外，两个其他非捕获元字符创建被称为”预测先行”匹配的某些内容。正向预测先行使用 ?= 指定，它匹配处于括号中匹配正则表达式模式的起始点的搜索字符串。反向预测先行使用 ?! 指定，它匹配处于与正则表达式模式不匹配的字符串的起始点的搜索字符串。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;例如，假设您有一个文档，该文档包含指向 Windows 3.1、Windows 95、Windows 98 和 Windows NT 的引用。再进一步假设，您需要更新该文档，将指向 Windows 95、Windows 98 和 Windows NT 的所有引用更改为 Windows 2000。下面的正则表达式（这是一个正向预测先行的示例）匹配 Windows 95、Windows 98 和 Windows NT：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/Windows(?=95 |98 |NT )/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;找到一处匹配后，紧接着就在匹配的文本（不包括预测先行中的字符）之后搜索下一处匹配。例如，如果上面的表达式匹配 Windows 98，将在 Windows 之后而不是在 98 之后继续搜索。</p>
<h2 id="其他示例"><a href="#其他示例" class="headerlink" title="其他示例"></a>其他示例</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;下面列出一些正则表达式示例：<br>正则表达式|描述<br>—|—<br>/\b([a-z]+) \1\b/gi    |一个单词连续出现的位置。<br>/(\w+):\/\/([^/:]+)(:\d<em>)?([^# ]</em>)/    |将一个URL解析为协议、域、端口及相对路径。<br>/^(?:Chapter|Section) [1-9][0-9]{0,1}$/    |定位章节的位置。<br>/[-a-z]/    |a至z共26个字母再加一个-号。<br>/ter\b/    |可匹配chapter，而不能匹配terminal。<br>/\Bapt/    |可匹配chapter，而不能匹配aptitude。<br>/Windows(?=95 |98 |NT )/    |可匹配Windows95或Windows98或WindowsNT，当找到一个匹配后，从Windows后面开始进行下一次的检索匹配。<br>/^\s<em>$/    |匹配空行。<br>/\d{2}-\d{5}/    |验证由两位数字、一个连字符再加 5 位数字组成的 ID 号。<br>/&lt;\s</em>(\S+)(\s[^&gt;]<em>)?&gt;[\s\S]</em>&lt;\s<em>\/\1\s</em>&gt;/    |匹配 HTML 标记。</p>

	

	

</article>




	<article>
	
		<h1><a href="/2017/10/12/正则表达式/5. 正则表达式-匹配规则/">正则表达式-匹配规则</a></h1>
	
	<div class="article__infos">
		<span class="article__date">2017-10-12</span><br />
		
		
			<span class="article__tags">
			  	<a class="article__tag-link" href="/tags/正则表达式/">正则表达式</a>
			</span>
		
	</div>

	

	
		<h2 id="基本模式匹配"><a href="#基本模式匹配" class="headerlink" title="基本模式匹配"></a>基本模式匹配</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;一切从最基本的开始。模式，是正规表达式最基本的元素，它们是一组描述字符串特征的字符。模式可以很简单，由普通的字符串组成，也可以非常复杂，往往用特殊的字符表示一个范围内的字符、重复出现，或表示上下文。例如：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">^once</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;这个模式包含一个特殊的字符^，表示该模式只匹配那些以once开头的字符串。例如该模式与字符串”once upon a time”匹配，与”There once was a man from NewYork”不匹配。正如如^符号表示开头一样，$符号用来匹配那些以给定模式结尾的字符串。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">bucket$</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;这个模式与”Who kept all of this cash in a bucket”匹配，与”buckets”不匹配。字符^和$同时使用时，表示精确匹配（字符串与模式一样）。例如：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">^bucket$</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;只匹配字符串”bucket”。如果一个模式不包括^和$，那么它与任何包含该模式的字符串匹配。例如：模式</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">once</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;与字符串</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">There once was a man from NewYork</div><div class="line">Who kept all of his cash <span class="keyword">in</span> a bucket.</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;是匹配的。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;在该模式中的字母(o-n-c-e)是字面的字符，也就是说，他们表示该字母本身，数字也是一样的。其他一些稍微复杂的字符，如标点符号和白字符（空格、制表符等），要用到转义序列。所有的转义序列都用反斜杠()打头。制表符的转义序列是：\t。所以如果我们要检测一个字符串是否以制表符开头，可以用这个模式：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">^\t</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;类似的，用\n表示”新行”，\r表示回车。其他的特殊符号，可以用在前面加上反斜杠，如反斜杠本身用\表示，句号.用.表示，以此类推。</p>
<h2 id="字符簇"><a href="#字符簇" class="headerlink" title="字符簇"></a>字符簇</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;在INTERNET的程序中，正规表达式通常用来验证用户的输入。当用户提交一个FORM以后，要判断输入的电话号码、地址、EMAIL地址、信用卡号码等是否有效，用普通的基于字面的字符是不够的。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;所以要用一种更自由的描述我们要的模式的办法，它就是字符簇。要建立一个表示所有元音字符的字符簇，就把所有的元音字符放在一个方括号里：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">[AaEeIiOoUu]</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;这个模式与任何元音字符匹配，但只能表示一个字符。用连字号可以表示一个字符的范围，如：</p>
<ul>
<li>[a-z] //匹配所有的小写字母 </li>
<li>[A-Z] //匹配所有的大写字母 </li>
<li>[a-zA-Z] //匹配所有的字母 </li>
<li>[0-9] //匹配所有的数字 </li>
<li>[0-9.-] //匹配所有的数字，句号和减号 </li>
<li>[ \f\r\t\n] //匹配所有的白字符</li>
</ul>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;同样的，这些也只表示一个字符，这是一个非常重要的。如果要匹配一个由一个小写字母和一位数字组成的字符串，比如”z2”、”t6”或”g7”，但不是”ab2”、”r2d3” 或”b52”的话，用这个模式：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">^[a-z][0-9]$</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;尽管[a-z]代表26个字母的范围，但在这里它只能与第一个字符是小写字母的字符串匹配。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;前面曾经提到^表示字符串的开头，但它还有另外一个含义。当在一组方括号里使用^是，它表示”非”或”排除”的意思，常常用来剔除某个字符。还用前面的例子，我们要求第一个字符不能是数字：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">^[^0-9][0-9]$</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;这个模式与”&amp;5”、”g7”及”-2”是匹配的，但与”12”、”66”是不匹配的。下面是几个排除特定字符的例子：</p>
<ul>
<li>[^a-z] //除了小写字母以外的所有字符 </li>
<li>[^\\/\^] //除了()(/)(^)之外的所有字符 </li>
<li>[^\”\’] //除了双引号(“)和单引号(‘)之外的所有字符</li>
</ul>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;特殊字符”.” (点，句号)在正则表达式中用来表示除了”新行”之外的所有字符。所以模式”^.5$”与任何两个字符的、以数字5结尾和以其他非”新行”字符开头的字符串匹配。模式”.”可以匹配任何字符串，除了空串和只包括一个”新行”的字符串。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;PHP的正规表达式有一些内置的通用字符簇，列表如下：</p>
<table>
<thead>
<tr>
<th>字符簇</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>[[:alpha:]]</td>
<td>任何字母</td>
</tr>
<tr>
<td>[[:digit:]]</td>
<td>任何数字</td>
</tr>
<tr>
<td>[[:alnum:]]</td>
<td>任何字母和数字</td>
</tr>
<tr>
<td>[[:space:]]</td>
<td>任何空白字符</td>
</tr>
<tr>
<td>[[:upper:]]</td>
<td>任何大写字母</td>
</tr>
<tr>
<td>[[:lower:]]</td>
<td>任何小写字母</td>
</tr>
<tr>
<td>[[:punct:]]</td>
<td>任何标点符号</td>
</tr>
<tr>
<td>[[:xdigit:]]</td>
<td>任何16进制的数字，相当于[0-9a-fA-F]</td>
</tr>
</tbody>
</table>
<h2 id="确定重复出现"><a href="#确定重复出现" class="headerlink" title="确定重复出现"></a>确定重复出现</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;到现在位置，已经知道如何去匹配一个字母或数字，但更多的情况下，可能要匹配一个单词或一组数字。一个单词有若干个字母组成，一组数字有若干个单数组成。跟在字符或字符簇后面的花括号({})用来确定前面的内容的重复出现的次数。</p>
<table>
<thead>
<tr>
<th>字符簇</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>\^[a-zA-Z_]$</td>
<td>所有的字母和下划线</td>
</tr>
<tr>
<td>\^[[:alpha:]]{3}$</td>
<td>所有的3个字母的单词</td>
</tr>
<tr>
<td>^a$</td>
<td>字母a</td>
</tr>
<tr>
<td>^a{4}$</td>
<td>aaaa</td>
</tr>
<tr>
<td>^a{2,4}$</td>
<td>aa,aaa或aaaa</td>
</tr>
<tr>
<td>^a{1,3}$</td>
<td>a,aa或aaa</td>
</tr>
<tr>
<td>^a{2,}$</td>
<td>包含多于两个a的字符串</td>
</tr>
<tr>
<td>^a{2,}</td>
<td>如：aardvark和aaab，但apple不行</td>
</tr>
<tr>
<td>a{2,}</td>
<td>如：baad和aaa，但Nantucket不行</td>
</tr>
<tr>
<td>\t{2}</td>
<td>两个制表符</td>
</tr>
<tr>
<td>.{2}</td>
<td>所有的两个字符</td>
</tr>
</tbody>
</table>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;这些例子描述了花括号的三种不同的用法。一个数字 <code>{x}</code> 的意思是<strong>前面的字符或字符簇只出现x次</strong> ；一个数字加逗号 <code>{x,}</code> 的意思是<strong>前面的内容出现x或更多的次数</strong> ；两个数字用逗号分隔的数字 <code>{x,y}</code> 表示 <strong>前面的内容至少出现x次，但不超过y次</strong>。我们可以把模式扩展到更多的单词或数字：</p>
<ul>
<li>^[a-zA-Z0-9_]{1,}$      // 所有包含一个以上的字母、数字或下划线的字符串 </li>
<li>^[1-9][0-9]{0,}$        // 所有的正整数 </li>
<li>^-{0,1}[0-9]{1,}$      // 所有的整数 </li>
<li>^[-]?[0-9]+.?[0-9]+$   // 所有的浮点数</li>
</ul>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;最后一个例子不太好理解，是吗？这么看吧：以一个可选的负号 <code>([-]?)</code> 开头 <code>(^)</code>、跟着1个或更多的数字(<code>[0-9]+</code>)、和一个小数点(<code>\.</code>)再跟上1个或多个数字(<code>[0-9]+</code>)，并且后面没有其他任何东西(<code>$</code>)。下面你将知道能够使用的更为简单的方法。<br>特殊字符 <code>?</code> 与 <code>{0,1}</code> 是相等的，它们都代表着： <strong>0个或1个前面的内容 或 前面的内容是可选的</strong> 。所以刚才的例子可以简化为：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">^\-?[0-9]&#123;1,&#125;\.?[0-9]&#123;1,&#125;$</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;特殊字符 <code>*</code> 与 <code>{0,}</code> 是相等的，它们都代表着 <strong>0 个或多个前面的内容</strong> 。最后，字符 <code>+</code> 与 <code>{1,}</code> 是相等的，表示 <strong>1 个或多个前面的内容</strong> ，所以上面的4个例子可以写成：</p>
<ul>
<li>^[a-zA-Z0-9_]+$      // 所有包含一个以上的字母、数字或下划线的字符串 </li>
<li>^[1-9][0-9]*$        // 所有的正整数 </li>
<li>^-?[0-9]+$          // 所有的整数 </li>
<li>^-?[0-9]+.?[0-9]*$ // 所有的浮点数</li>
</ul>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;当然这并不能从技术上降低正规表达式的复杂性，但可以使它们更容易阅读。</p>

	

	

</article>




	<article>
	
		<h1><a href="/2017/10/12/正则表达式/4. 正则表达式-运算符优先级/">正则表达式-运算符优先级</a></h1>
	
	<div class="article__infos">
		<span class="article__date">2017-10-12</span><br />
		
		
			<span class="article__tags">
			  	<a class="article__tag-link" href="/tags/正则表达式/">正则表达式</a>
			</span>
		
	</div>

	

	
		<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;正则表达式从左到右进行计算，并遵循优先级顺序，这与算数表达式非常类似。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;相同优先级的从左到右进行运算，不同优先级的运算先高后低。下表从最高到最低说明了各种正则表达式运算符的优先级顺序：</p>
<table>
<thead>
<tr>
<th>运算符</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>\</td>
<td>转义符</td>
</tr>
<tr>
<td>(),(?:),(?=),[]</td>
<td>圆括号和方括号</td>
</tr>
<tr>
<td>*,+,?,{n},{n,},{n,m}</td>
<td>限定符</td>
</tr>
<tr>
<td>^,$，\任何元字符、任何字符</td>
<td>定位点和序列（即：位置和顺序）</td>
</tr>
<tr>
<td>\</td>
<td></td>
<td>替换，“或”操作，字符具有高于替换运算符的优先级，使得“m</td>
<td>food”匹配“m”或“food”。若要匹配“mood”或“food”，使用括号创建子表达式，从而产生“(m</td>
<td>f)ood”</td>
</tr>
</tbody>
</table>

	

	

</article>




	<article>
	
		<h1><a href="/2017/10/12/正则表达式/3. 正则表达式-元字符/">正则表达式-元字符</a></h1>
	
	<div class="article__infos">
		<span class="article__date">2017-10-12</span><br />
		
		
			<span class="article__tags">
			  	<a class="article__tag-link" href="/tags/正则表达式/">正则表达式</a>
			</span>
		
	</div>

	

	
		<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;下标包含了元字符的完整列表以及他们在正则表达式上下文中的行为：</p>
<table>
<thead>
<tr>
<th>字符</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>\</td>
<td>将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如，’n’ 匹配字符 “n”。’\n’ 匹配一个换行符。序列 ‘\‘ 匹配 “\” 而 “(“ 则匹配 “(“。</td>
</tr>
<tr>
<td>^</td>
<td>匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性，^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。</td>
</tr>
<tr>
<td>$</td>
<td>匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性，$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。</td>
</tr>
<tr>
<td>*</td>
<td>匹配前面的子表达式零次或多次。例如，zo<em> 能匹配 “z” 以及 “zoo”。</em> 等价于{0,}。</td>
</tr>
<tr>
<td>+</td>
<td>匹配前面的子表达式一次或多次。例如，’zo+’ 能匹配 “zo” 以及 “zoo”，但不能匹配 “z”。+ 等价于 {1,}。</td>
</tr>
<tr>
<td>?</td>
<td>匹配前面的子表达式零次或一次。例如，”do(es)?” 可以匹配 “do” 或 “does” 中的”do” 。? 等价于 {0,1}。</td>
</tr>
<tr>
<td>{n}</td>
<td>n 是一个非负整数。匹配确定的 n 次。例如，’o{2}’ 不能匹配 “Bob” 中的 ‘o’，但是能匹配 “food” 中的两个 o。</td>
</tr>
<tr>
<td>{n,}</td>
<td>n 是一个非负整数。至少匹配n 次。例如，’o{2,}’ 不能匹配 “Bob” 中的 ‘o’，但能匹配 “foooood” 中的所有 o。’o{1,}’ 等价于 ‘o+’。’o{0,}’ 则等价于 ‘o*’。</td>
</tr>
<tr>
<td>{n,m}</td>
<td>m 和 n 均为非负整数，其中n &lt;= m。最少匹配 n 次且最多匹配 m 次。例如，”o{1,3}” 将匹配 “fooooood” 中的前三个 o。’o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。</td>
</tr>
<tr>
<td>?</td>
<td>当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时，匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串，而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如，对于字符串 “oooo”，’o+?’ 将匹配单个 “o”，而 ‘o+’ 将匹配所有 ‘o’。</td>
</tr>
<tr>
<td>.</td>
<td>匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符，请使用像”(.</td>
<td>\n)”的模式。</td>
</tr>
<tr>
<td>(pattern)</td>
<td>匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到，在VBScript 中使用 SubMatches 集合，在JScript 中则使用 $0…$9 属性。要匹配圆括号字符，请使用 ‘(‘ 或 ‘)‘。</td>
</tr>
<tr>
<td>(?:pattern)</td>
<td>匹配 pattern 但不获取匹配结果，也就是说这是一个非获取匹配，不进行存储供以后使用。这在使用 “或” 字符 (</td>
<td>) 来组合一个模式的各个部分是很有用。例如， ‘industr(?:y</td>
<td>ies) 就是一个比 ‘industry</td>
<td>industries’ 更简略的表达式。</td>
</tr>
<tr>
<td>(?=pattern)</td>
<td>正向预查，在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如，’Windows (?=95</td>
<td>98</td>
<td>NT</td>
<td>2000)’ 能匹配 “Windows 2000” 中的 “Windows” ，但不能匹配 “Windows 3.1” 中的 “Windows”。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始。</td>
</tr>
<tr>
<td>(?!pattern)</td>
<td>负向预查，在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如’Windows (?!95</td>
<td>98</td>
<td>NT</td>
<td>2000)’ 能匹配 “Windows 3.1” 中的 “Windows”，但不能匹配 “Windows 2000” 中的 “Windows”。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始。</td>
</tr>
<tr>
<td>x\</td>
<td>y</td>
<td>匹配 x 或 y。例如，’z</td>
<td>food’ 能匹配 “z” 或 “food”。’(z</td>
<td>f)ood’ 则匹配 “zood” 或 “food”。</td>
</tr>
<tr>
<td>[xyz]</td>
<td>字符集合。匹配所包含的任意一个字符。例如， ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。</td>
</tr>
<tr>
<td>[^xyz]</td>
<td>负值字符集合。匹配未包含的任意字符。例如， ‘[^abc]’ 可以匹配 “plain” 中的’p’、’l’、’i’、’n’。</td>
</tr>
<tr>
<td>[a-z]</td>
<td>字符范围。匹配指定范围内的任意字符。例如，’[a-z]’ 可以匹配 ‘a’ 到 ‘z’ 范围内的任意小写字母字符。</td>
</tr>
<tr>
<td>[^a-z]</td>
<td>负值字符范围。匹配任何不在指定范围内的任意字符。例如，’[^a-z]’ 可以匹配任何不在 ‘a’ 到 ‘z’ 范围内的任意字符。</td>
</tr>
<tr>
<td>\b</td>
<td>匹配一个单词边界，也就是指单词和空格间的位置。例如， ‘er\b’ 可以匹配”never” 中的 ‘er’，但不能匹配 “verb” 中的 ‘er’。</td>
</tr>
<tr>
<td>\B</td>
<td>匹配非单词边界。’er\B’ 能匹配 “verb” 中的 ‘er’，但不能匹配 “never” 中的 ‘er’。</td>
</tr>
<tr>
<td>\cx</td>
<td>匹配由 x 指明的控制字符。例如， \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则，将 c 视为一个原义的 ‘c’ 字符。</td>
</tr>
<tr>
<td>\d</td>
<td>匹配一个数字字符。等价于 [0-9]。</td>
</tr>
<tr>
<td>\D</td>
<td>匹配一个非数字字符。等价于 [^0-9]。</td>
</tr>
<tr>
<td>\f</td>
<td>匹配一个换页符。等价于 \x0c 和 \cL。</td>
</tr>
<tr>
<td>\n</td>
<td>匹配一个换行符。等价于 \x0a 和 \cJ。</td>
</tr>
<tr>
<td>\r</td>
<td>匹配一个回车符。等价于 \x0d 和 \cM。</td>
</tr>
<tr>
<td>\s</td>
<td>匹配任何空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。</td>
</tr>
<tr>
<td>\S</td>
<td>匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。</td>
</tr>
<tr>
<td>\t</td>
<td>匹配一个制表符。等价于 \x09 和 \cI。</td>
</tr>
<tr>
<td>\v</td>
<td>匹配一个垂直制表符。等价于 \x0b 和 \cK。</td>
</tr>
<tr>
<td>\w</td>
<td>匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’。</td>
</tr>
<tr>
<td>\W</td>
<td>匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]’。</td>
</tr>
<tr>
<td>\xn</td>
<td>匹配 n，其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如，’\x41’ 匹配 “A”。’\x041’ 则等价于 ‘\x04’ &amp; “1”。正则表达式中可以使用 ASCII 编码。</td>
</tr>
<tr>
<td>\num</td>
<td>匹配 num，其中 num 是一个正整数。对所获取的匹配的引用。例如，’(.)\1’ 匹配两个连续的相同字符。</td>
</tr>
<tr>
<td>\n</td>
<td>标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式，则 n 为向后引用。否则，如果 n 为八进制数字 (0-7)，则 n 为一个八进制转义值。</td>
</tr>
<tr>
<td>\nm</td>
<td>标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式，则 nm 为向后引用。如果 \nm 之前至少有 n 个获取，则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足，若 n 和 m 均为八进制数字 (0-7)，则 \nm 将匹配八进制转义值 nm。</td>
</tr>
<tr>
<td>\nml</td>
<td>如果 n 为八进制数字 (0-3)，且 m 和 l 均为八进制数字 (0-7)，则匹配八进制转义值 nml。</td>
</tr>
<tr>
<td>\un</td>
<td>匹配 n，其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如， \u00A9 匹配版权符号 (?)。</td>
</tr>
</tbody>
</table>

	

	

</article>




	<article>
	
		<h1><a href="/2017/10/12/正则表达式/2. 正则表达式-语法/">正则表达式-语法</a></h1>
	
	<div class="article__infos">
		<span class="article__date">2017-10-12</span><br />
		
		
			<span class="article__tags">
			  	<a class="article__tag-link" href="/tags/正则表达式/">正则表达式</a>
			</span>
		
	</div>

	

	
		<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;正则表达式（regular expression）描述了一种字符串匹配的模式（pattern），可以 用来检查一个串是否含有某种子串。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;将匹配的子串替换或者从某个串中取出符合某个条件的子串等。</p>
<ul>
<li><code>runoo+b</code> ，可以匹配 runoob、runooob、runoooooob等，+ 号代表前面的字符必须至少出现一次（1次或多次）。</li>
<li><code>runoo*b</code> ，可以匹配runob、runoob、runoooooob等，* 号代表字符可以不出现，也可以出现一次或多次（0次、1次、或多次）。</li>
<li><code>colou?r</code> ，可以匹配color或者colour，？问号代表前面的字符最多只可以出现一次（0次、1次）。</li>
</ul>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与运算符可以将小的表达式结合在一起来创建更大个表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。  </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;正则表达式是由普通字符（如字符a到z）以及特殊字符（称为“元字符”）组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模版，将某个字符模式与所搜索的字符串进行匹配</p>
<h2 id="普通字符"><a href="#普通字符" class="headerlink" title="普通字符"></a>普通字符</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;普通字符包括没有显示指定为元字符的所有可打印和不可打印的字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。</p>
<h2 id="非打印字符"><a href="#非打印字符" class="headerlink" title="非打印字符"></a>非打印字符</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;非打印字符也可以是正则表达式的组成部分。下标列出了表示非打印字符的转义序列：</p>
<table>
<thead>
<tr>
<th>字符</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>\cx</td>
<td>匹配由x指明的控制字符。例如， \cM</td>
<td>匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则，将 c 视为一个原义的 ‘c’ 字符。</td>
</tr>
<tr>
<td>\f</td>
<td>匹配一个换页符。等价于 \x0c 和 \cL。</td>
</tr>
<tr>
<td>\n</td>
<td>匹配一个换行符。等价于 \x0a 和 \cJ。</td>
</tr>
<tr>
<td>\r</td>
<td>匹配一个回车符。等价于 \x0d 和 \cM。</td>
</tr>
<tr>
<td>\s</td>
<td>匹配任何空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。</td>
</tr>
<tr>
<td>\S</td>
<td>匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。</td>
</tr>
<tr>
<td>\t</td>
<td>匹配一个制表符。等价于 \x09 和 \cI。</td>
</tr>
<tr>
<td>\v</td>
<td>匹配一个垂直制表符。等价于 \x0b 和 \cK。</td>
</tr>
</tbody>
</table>
<h2 id="特殊字符"><a href="#特殊字符" class="headerlink" title="特殊字符"></a>特殊字符</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;所谓特殊字符，就是一些有特殊含义的字符，如上面说的 <code>runoo*b</code> 中的 <code>*</code>，简单的说就是表示任何字符串的意思。如果要查找字符串中的 <code>*</code> 符号，则需要对 <code>*</code> 进行转义，即在其前加一个 <code>\</code>: <code>runo\*ob</code> 匹配 runo*ob。 </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符，必须首先使字符”转义”，即，将反斜杠字符\ 放在它们前面。下表列出了正则表达式中的特殊字符：</p>
<table>
<thead>
<tr>
<th>特别字符</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>$</td>
<td>匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性，则 $ 也匹配 ‘\n’ 或 ‘\r’。要匹配 $ 字符本身，请使用 \$。</td>
</tr>
<tr>
<td>( )</td>
<td>标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符，请使用 \( 和 \)。</td>
</tr>
<tr>
<td>*</td>
<td>匹配前面的子表达式零次或多次。要匹配 <em> 字符，请使用 \</em>。</td>
</tr>
<tr>
<td>+</td>
<td>匹配前面的子表达式一次或多次。要匹配 + 字符，请使用 \+。</td>
</tr>
<tr>
<td>.</td>
<td>匹配除换行符 \n 之外的任何单字符。要匹配 . ，请使用 \. 。</td>
</tr>
<tr>
<td>[</td>
<td>标记一个中括号表达式的开始。要匹配 [，请使用 \[。</td>
</tr>
<tr>
<td>?</td>
<td>匹配前面的子表达式零次或一次，或指明一个非贪婪限定符。要匹配 ? 字符，请使用 \?。</td>
</tr>
<tr>
<td>\</td>
<td>将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如， ‘n’ 匹配字符 ‘n’。’\n’ 匹配换行符。序列 ‘\\’ 匹配 “\“，而 ‘\(‘ 则匹配 “(“。</td>
</tr>
<tr>
<td>^</td>
<td>匹配输入字符串的开始位置，除非在方括号表达式中使用，此时它表示不接受该字符集合。要匹配 ^ 字符本身，请使用 \^。</td>
</tr>
<tr>
<td>{</td>
<td>标记限定符表达式的开始。要匹配 {，请使用 \{。</td>
</tr>
<tr>
<td>\</td>
<td></td>
<td>指明两项之间的一个选择。要匹配 \</td>
<td>，请使用 \\</td>
<td>。</td>
</tr>
</tbody>
</table>
<h2 id="限定符"><a href="#限定符" class="headerlink" title="限定符"></a>限定符</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有<code>*</code>或<code>+</code>或<code>?</code>或<code>{n}</code>或<code>{n,}</code>或<code>{n,m}</code>共6种。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;正则表达式的限定符有：</p>
<table>
<thead>
<tr>
<th>字符</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>*</td>
<td>匹配前面的子表达式零次或多次。例如，zo<em> 能匹配 “z” 以及 “zoo”。</em> 等价于{0,}。</td>
</tr>
<tr>
<td>+</td>
<td>匹配前面的子表达式一次或多次。例如，’zo+’ 能匹配 “zo” 以及 “zoo”，但不能匹配 “z”。+ 等价于 {1,}。</td>
</tr>
<tr>
<td>?</td>
<td>匹配前面的子表达式零次或一次。例如，”do(es)?” 可以匹配 “do” 或 “does” 中的”do” 。? 等价于 {0,1}。</td>
</tr>
<tr>
<td>{n}</td>
<td>n 是一个非负整数。匹配确定的 n 次。例如，’o{2}’ 不能匹配 “Bob” 中的 ‘o’，但是能匹配 “food” 中的两个 o。</td>
</tr>
<tr>
<td>{n,}</td>
<td>n 是一个非负整数。至少匹配n 次。例如，’o{2,}’ 不能匹配 “Bob” 中的 ‘o’，但能匹配 “foooood” 中的所有 o。’o{1,}’ 等价于 ‘o+’。’o{0,}’ 则等价于 ‘o*’。</td>
</tr>
<tr>
<td>{n,m}</td>
<td>m 和 n 均为非负整数，其中n &lt;= m。最少匹配 n 次且最多匹配 m 次。例如，”o{1,3}” 将匹配 “fooooood” 中的前三个 o。’o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。</td>
</tr>
</tbody>
</table>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;由于章节编号在大的输入文档中会很可能超过九，所以需要一种方式来处理两位或三位章节编号。限定符有这种能力。下面的正则表达式匹配编号为任何位数的章节标题：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/Chapter [1-9][0-9]*/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;注意，限定符出现在范围表达式之后。因此，它应用于整个范围表达式，在本例中，只指定从 0 到 9 的数字（包括 0 和 9）。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;这里不使用 + 限定符，因为在第二个位置或后面的位置不一定需要有一个数字。也不使用？字符，因为它将章节编号限制到只有两位数。您需要至少匹配 Chapter 和空格字符后面的一个数字。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;如果知道章节编号被限制为只有 99 章，可以使用下面的表达式来至少指定一位但至多两位数字。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/Chapter [0-9]&#123;1,2&#125;/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;上面的表达式的缺点是，大于 99 的章节编号仍只匹配开头两位数字。另一个缺点是 Chapter 0 也将匹配。只匹配两位数字的更好的表达式如下：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/Chapter [1-9][0-9]?/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;或</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/Chapter [1-9][0-9]&#123;0,1&#125;/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<strong>*、+和?限定符都是贪婪的，因为它们会尽可能多的匹配文字，只有在它们的后面加上一个?就可以实现非贪婪或最小匹配。</strong></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;例如，可能搜索 HTML 文档，以查找括在 H1 标记内的章节标题。该文本在文档中如下：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">&lt;H1&gt;Chapter 1 - 介绍正则表达式&lt;/H1&gt;</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<strong>贪婪</strong>：下面的表达式匹配从开始小于符号 (&lt;) 到关闭 H1 标记的大于符号 (&gt;) 之间的所有内容。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/&lt;.*&gt;/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<strong>非贪婪</strong>：如果只需要匹配开始和介绍 H1 标记，下面的非贪婪表达式只匹配 </p><h1>。<p></p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/&lt;.*?&gt;/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;如果只想匹配开始的 H1 标签，表达式则是：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/&lt;\w+?&gt;/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;通过在 <code>*</code>、<code>+</code> 或 <code>?</code> 限定符之后放置 ?，该表达式从”贪心”表达式转换为”非贪心”表达式或者最小匹配。</p>
<h2 id="定位符"><a href="#定位符" class="headerlink" title="定位符"></a>定位符</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;定位符能够将正则表达式固定到行首或行尾。它们还能够创建这样的正则表达式，这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;定位符用来描述字符串或单词的边界，<code>^</code> 和 <code>$</code> 分别指字符串的开始与结束，span class=”marked”&gt;\b 描述单词的前或后边界，span class=”marked”&gt;\B 表示非单词边界。 </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;正则表达式的限定符有：</p>
<table>
<thead>
<tr>
<th>字符</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>^</td>
<td>匹配输入字符串开始的位置。如果设置了RegExp对象的Multiline属性，^还会与\n或\r之后的位置匹配</td>
</tr>
<tr>
<td>$</td>
<td>匹配输入字符串结尾的位置。如果设置了RegExp对象的Multiline属性，$还回与\n或\r之前的位置匹配</td>
</tr>
<tr>
<td>\b</td>
<td>匹配一个字边界，即字与空格间的位置</td>
</tr>
<tr>
<td>\B</td>
<td>非字边界匹配</td>
</tr>
</tbody>
</table>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<strong>注意</strong>：不能将限定符与定位点一起使用。由于在紧靠换行或者字边界的前面或后面不能有一个以上位置，因此不允许诸如 <code>^*</code> 之类的表达式。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;若要匹配一行文本开始处的文本，请在正则表达式的开始使用 <code>^</code> 字符。不要将 <code>^</code> 的这种用法与中括号表达式内的用法混淆。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;若要匹配一行文本的结束处的文本，请在正则表达式的结束处使用 <code>$</code>字符。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;若要在搜索章节标题时使用定位点，下面的正则表达式匹配一个章节标题，该标题只包含两个尾随数字，并且出现在行首：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/^Chapter [1-9][0-9]&#123;0,1&#125;/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;真正的章节标题不仅出现行的开始处，而且它还是该行中仅有的文本。它即出现在行首又出现在同一行的结尾。下面的表达式能确保指定的匹配只匹配章节而不匹配交叉引用。通过创建只匹配一行文本的开始和结尾的正则表达式，就可做到这一点。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/^Chapter [1-9][0-9]&#123;0,1&#125;$/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;匹配字边界稍有不同，但向正则表达式添加了很重要的能力。字边界是单词和空格之间的位置。非字边界是任何其他位置。下面的表达式匹配单词 Chapter 的开头三个字符，因为这三个字符出现字边界后面：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/\bCha/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<code>\b</code> 字符的位置是非常重要的。如果它位于要匹配的字符串的开始，它在单词的开始处查找匹配项。如果它位于字符串的结尾，它在单词的结尾处查找匹配项。例如，下面的表达式匹配单词 Chapter 中的字符串 ter，因为它出现在字边界的前面：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/ter\b/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;下面的表达式匹配 Chapter 中的字符串 apt，但不匹配 aptitude 中的字符串 apt：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/\Bapt/</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;字符串 apt 出现在单词 Chapter 中的非字边界处，但出现在单词 aptitude 中的字边界处。对于 \B 非字边界运算符，位置并不重要，因为匹配不关心究竟是单词的开头还是结尾。</p>
<h2 id="选择"><a href="#选择" class="headerlink" title="选择"></a>选择</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;用圆括号将所有选择项括起来，相邻的选择项之间用|分隔。但用圆括号会有一个副作用，是相关的匹配会被缓存，此时可用?:放在第一个选项前来消除这种副作用。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;其中 <code>?:</code> 是非捕获元之一，还有两个非捕获元是 <code>?=</code> 和 <code>?!</code>，这两个还有更多的含义，前者为正向预查，在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串，后者为负向预查，在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。</p>
<h2 id="反向引用"><a href="#反向引用" class="headerlink" title="反向引用"></a>反向引用</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中，所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始，最多可存储 99 个捕获的子表达式。每个缓冲区都可以使用 \n 访问，其中 n 为一个标识特定缓冲区的一位或两位十进制数。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;可以使用非捕获元字符 <code>?:</code>、<code>?=</code> 或 <code>?!</code> 来重写捕获，忽略对相关匹配的保存。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;反向引用的最简单的、最有用的应用之一，是提供查找文本中两个相同的相邻单词的匹配项的能力。以下面的句子为例：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">Is is the cost of of gasoline going up up?</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;上面的句子很显然有多个重复的单词。如果能设计一种方法定位该句子，而不必查找每个单词的重复出现，那该有多好。下面的正则表达式使用单个子表达式来实现这一点：</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;查找重复的单词：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">var str = <span class="string">"Is is the cost of of gasoline going up up"</span>;</div><div class="line">var patt1 = /\b([a-z]+) \1\b/;</div><div class="line">document.write(str.match(patt1));</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;捕获的表达式，正如 <code>[a-z]+</code> 指定的，包括一个或多个字母。正则表达式的第二部分是对以前捕获的子匹配项的引用，即，单词的第二个匹配项正好由括号表达式匹配。<code>\1</code> 指定第一个子匹配项。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;字边界元字符确保只检测整个单词。否则，诸如 “is issued” 或 “this is” 之类的词组将不能正确地被此表达式识别。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;正则表达式后面的全局标记 <code>g</code> 指定将该表达式应用到输入字符串中能够查找到的尽可能多的匹配。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;表达式的结尾处的不区分大小写 <code>i</code> 标记指定不区分大小写。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;多行标记指定换行符的两边可能出现潜在的匹配。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;反向引用还可以将通用资源指示符 (URI) 分解为其组件。假定您想将下面的 URI 分解为协议（ftp、http 等等）、域地址和页/路径：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">http://www.runoob.com:80/html/html-tutorial.html</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;下面的正则表达式提供该功能：</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;输出所有匹配的数据：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">var str = <span class="string">"https://www.runoob.com:80/html/html-tutorial.html"</span>;</div><div class="line">var patt1 = /(\w+):\/\/([^/:]+)(:\d*)?([^<span class="comment"># ]*)/;</span></div><div class="line">arr = str.match(patt1);</div><div class="line"><span class="keyword">for</span> (var i = 0; i &lt; arr.length ; i++) &#123;</div><div class="line">    document.write(arr[i]);</div><div class="line">    document.write(<span class="string">"&lt;br&gt;"</span>);</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;第一个括号子表达式捕获 Web 地址的协议部分。该子表达式匹配在冒号和两个正斜杠前面的任何单词。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;第二个括号子表达式捕获地址的域地址部分。子表达式匹配 / 和 : 之外的一个或多个字符。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;第三个括号子表达式捕获端口号（如果指定了的话）。该子表达式匹配冒号后面的零个或多个数字。只能重复一次该子表达式。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;最后，第四个括号子表达式捕获 Web 地址指定的路径和 / 或页信息。该子表达式能匹配不包括 # 或空格字符的任何字符序列。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;将正则表达式应用到上面的 URI，各子匹配项包含下面的内容：</p>
<ul>
<li>第一个括号子表达式包含”http”</li>
<li>第二个括号子表达式包含”www.runoob.com”</li>
<li>第三个括号子表达式包含”:80”</li>
<li>第四个括号子表达式包含”/html/html-tutorial.html”</li>
</ul>
</h1>
	

	

</article>




	<article>
	
		<h1><a href="/2017/10/12/正则表达式/1. 正则表达式-简介/">正则表达式-简介</a></h1>
	
	<div class="article__infos">
		<span class="article__date">2017-10-12</span><br />
		
		
			<span class="article__tags">
			  	<a class="article__tag-link" href="/tags/正则表达式/">正则表达式</a>
			</span>
		
	</div>

	

	
		<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;正则表达式（Regular Expression）是一种文本模式，包括普通字符和特殊字符。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;正则表达式是繁琐的，但它是强大的，许多程序设计语言都支持利用正则表达式进行字符串操作。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;例如，使用 <code>?</code> 和 <code>*</code> 通配符来查找硬盘上的文件。<code>?</code> 通配符匹配文件名中的单个字符，而 <code>*</code> 通配符匹配零个或多个字符。像 <code>data?.dat</code> 这样的模式将查找下列文件：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">data1.dat</div><div class="line">data2.dat</div><div class="line">datax.dat</div><div class="line">dataN.dat</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;使用 <em> 字符代替 ？ 字符扩大了找到的文件数量。data</em>.dat 匹配烈夏所有文件：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">data.dat</div><div class="line">data1.dat</div><div class="line">data2.dat</div><div class="line">data12.dat</div><div class="line">datax.dat</div><div class="line">dataXYZ.dat</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;尽管这种搜索方法很有用，但它还是有限的。通过理解 * 通配符的工作原理，引入了正则表达式所依赖的概念，但正则表达式功能强大，而且更加灵活。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;正则表达式的使用，可以通过简单的办法来实现强大的功能。下面一个简单的示例：</p>
<p><strong>\^[0-9]+abc$</strong></p>
<ul>
<li><code>^</code> 为匹配输入字符串的开始位置。</li>
<li><code>[0-9]+</code> 匹配多个数字，<code>[0-9]</code> 匹配单个数字，<code>+</code> 匹配一个或者多个。</li>
<li><code>abc$</code> 匹配字母 <code>abc</code> 并以 <code>abc</code> 结尾， <code>$</code> 为匹配输入字符串的结束位置。</li>
</ul>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;实例：匹配以数字开头，并以 abc 结尾的字符串：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">var str = <span class="string">"123abc"</span>;</div><div class="line">var parr1 = /^[0-9]+abc$/;</div><div class="line">document.write(str.match(patt1));</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;以上标记的文本是获得的匹配的表达式：<code>123abc</code></p>
<h2 id="为什么使用正则表达式？"><a href="#为什么使用正则表达式？" class="headerlink" title="为什么使用正则表达式？"></a>为什么使用正则表达式？</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;典型的搜索和替换操作要求提供与预期的搜索结果匹配的确切文本。随谈这种技术对于静态文件执行简单搜索和替换任何可能已经足够了，但它缺乏灵活性，若采用这种方法搜索动态文本，几十不是不可能，至少也会变得很困难。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;通过是有那个正则表达式，可以：</p>
<ul>
<li>测试字符串内的模式。<br>例如，可以测试输入字符串，以查看字符串内是否出现电话号码模式或信用卡号码模式。这成为数据验证。</li>
<li>替换文本。<br>可以使用正则表达式来识别文档中的特定文本，完全删除该文本或者用其他文本替换它。</li>
<li>基于模式匹配从字符串中提取子字符串。<br>可以查找文档内或输入域内特定的文本。</li>
</ul>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;例如，可能需要搜索整个网站，删除过时的材料，以及替换某些 HTML 格式标记。在这种情况下，可以正则表达式来确定在每个文件中是否出现该材料或该 HTML 格式标记。此过程将受影响的文件裂变缩小到包含需要删除或更改的材料的那些文件。然后可以使用正则表达式来删除过世的材料。最后，可以使用正则表达式来搜索和替换标记。</p>
<h2 id="发展历史"><a href="#发展历史" class="headerlink" title="发展历史"></a>发展历史</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;正则表达式的“祖先”可以一直上溯至对人类神经系统如何工作的早期研究。Warren McCulloch 和 Walter Pitts 这两位神经胜利学家研究出一种数学方式来描述这些神经网络。 </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;1956年，一位叫 Stephen Kleene 的数学家在 McCulloch 和 Pitts 早期工作的基础上，发表了一篇标题为“神经网时间的表示法”的论文，引入了正则表达式的概念。正则表达式就是用来描述他称为“正则集的代数”的表达式，因此采用“正则表达式”这个术语。 </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;随后，发现可以将这一工作应用于使用 Ken Thompson 的计算搜索算法的一些早期研究，Ken Thompson 是 Unix 的主要发明人，正则表达式的第一个实用应用程序就是 Unix 中的 qed 编辑器。 </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;如他们所说，剩下的就是众所周知的历史了。从那时起直至现在正则表达式都是基于文件的表机器和搜索工具中的一个重要部分。</p>
<h2 id="应用领域"><a href="#应用领域" class="headerlink" title="应用领域"></a>应用领域</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;目前，正则表达式已经在很多软件中得到广泛应用，包括 Linux、Unix、HP等操作系统， PHP、C#、Java等开发环境，以及很多的应用软件中，都可以看到正则表达式的影子</p>
<table>
<thead>
<tr>
<th>命令或环境</th>
<th>.</th>
<th>[]</th>
<th>^</th>
<th>$</th>
<th>\(\)</th>
<th>\{\}</th>
<th>?</th>
<th>+</th>
<th>\</th>
<th></th>
<th>()</th>
</tr>
</thead>
<tbody>
<tr>
<td>vi</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Visual C++</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>awk</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td></td>
<td>awk是支持该语法的， 只是要在命令行加入 –posix or –re-interval参数即可， 可见man awk中的interval expression</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
</tr>
<tr>
<td>sed</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>delphi</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td></td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
</tr>
<tr>
<td>python</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
</tr>
<tr>
<td>java</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
</tr>
<tr>
<td>javascript</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td></td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
</tr>
<tr>
<td>php</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>perl</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td></td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
</tr>
<tr>
<td>C#</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
<td></td>
<td></td>
<td>√</td>
<td>√</td>
<td>√</td>
<td>√</td>
</tr>
</tbody>
</table>

	

	

</article>




	<article>
	
		<h1><a href="/2017/10/12/Zabbix/9. zabbix 配置邮件告警/">zabbix 配置邮件告警</a></h1>
	
	<div class="article__infos">
		<span class="article__date">2017-10-12</span><br />
		
		
			<span class="article__tags">
			  	<a class="article__tag-link" href="/tags/Zabbix/">Zabbix</a>
			</span>
		
	</div>

	

	
		<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;设置触发器的目的是为了让监控的服务实现告警，下面来配置一下邮件告警。发邮件是服务器通过子机的 sendmail 服务发出的，有时候如果配置不合适或者服务没有启动，是发不出邮件的。所以，要先测试一下。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">[root@zabbix ~]<span class="comment"># yum install -y sendmail</span></div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;启动服务</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">[root@zabbix ~]<span class="comment"># /etc/init.d/sendmail start</span></div></pre></td></tr></table></figure>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">[root@zabbix ~]<span class="comment"># echo "test mail"|mail -s "testtest" 89429541@qq.com</span></div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;如果提示</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/01.png?raw=true" alt="01"><figcaption class="figure__caption">01</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;安装</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">[root@zabbix ~]<span class="comment"># yum -y install mailx</span></div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;如果是虚拟机，很有可能是收不到邮件的，但如果是真机还是可以收到的，只不过有可能在垃圾邮件箱里。下面来配置 zabbix 的邮件告警。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">[root@zabbix ~]<span class="comment"># mkdir -p /home/zabbix/bin</span></div><div class="line">[root@zabbix ~]<span class="comment"># vim /home/zabbix/bin/baojing.sh</span></div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;内容为</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#!/bin/bash</span></div><div class="line"><span class="built_in">echo</span> <span class="string">"<span class="variable">$3</span>"</span>|/bin/mail -s <span class="string">"<span class="variable">$2</span>"</span> <span class="variable">$1</span></div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;保存后，修改文件的权限</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">[root@zabbix ~]<span class="comment"># chmod -x /home/zabbix/bin/baojing.sh</span></div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;在 /etc/zabbix_server.conf 配置文件中，有参数 AlertScriptePath 和 ExternalScripts ，编辑它</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">[root@zabbix ~]<span class="comment"># vim /etc/zabbix_server.conf</span></div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;修改如下内容</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/02.png?raw=true" alt="02"><figcaption class="figure__caption">02</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;修改为（用户自定义的 media type 脚本）</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/03.png?raw=true" alt="03"><figcaption class="figure__caption">03</figcaption></figure></p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/04.png?raw=true" alt="04"><figcaption class="figure__caption">04</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;修改为（用户自定义的检测的脚本 item）</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/05.png?raw=true" alt="05"><figcaption class="figure__caption">05</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;下面在浏览器里面继续配置邮件告警</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;创建 mediea type： “administration”（管理） –&gt; “Media type”（警示媒体类型） </p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/06.png?raw=true" alt="06"><figcaption class="figure__caption">06</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;点击右上角 “Create Media Type”（创建警示媒体类型）</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/07.png?raw=true" alt="07"><figcaption class="figure__caption">07</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;其中 Description（描述） 填 “baojing” 或其他自定义名称</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/08.png?raw=true" alt="08"><figcaption class="figure__caption">08</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Type（类型） 选择 “Script”（脚本）</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/09.png?raw=true" alt="09"><figcaption class="figure__caption">09</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Script 填 “baojing.sh” 然后点 “Save”（存档）</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/10.png?raw=true" alt="10"><figcaption class="figure__caption">10</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;创建 user：“Administration”（管理）–&gt; “User”（用户）</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/11.png?raw=true" alt="11"><figcaption class="figure__caption">11</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;在右上角，选择 “Users”（用户），点击 “Create User”（创建用户） </p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/12.png?raw=true" alt="12"><figcaption class="figure__caption">12</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;alias（别名）：test1，自定义 name（名称） 和 lastname（姓氏） password（密码）：123456； group（组） 选择 guest </p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/13.png?raw=true" alt="13"><figcaption class="figure__caption">13</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;回到上面点一下 media type（示警媒体）</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/14.png?raw=true" alt="14"><figcaption class="figure__caption">14</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;选择 baojing ，send to（收件人） 写要发送邮件的邮箱，点 add（添加） </p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/15.png?raw=true" alt="15"><figcaption class="figure__caption">15</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;最后点 save（存档）</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;创建action: “configuration”（配置） –&gt; actions（动作）</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/16.png?raw=true" alt="16"><figcaption class="figure__caption">16</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;右上角“Create Actions”（创建动作）</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/17.png?raw=true" alt="17"><figcaption class="figure__caption">17</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Name（名称）自定义，我这里写”baojing”,其他默认</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/18.png?raw=true" alt="18"><figcaption class="figure__caption">18</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;然后点右侧的“Operations”（操作）下的“New”（新的）按钮</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/19.png?raw=true" alt="19"><figcaption class="figure__caption">19</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;“Operation Type”（操作类型）选择“Send message”（送出消息）</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/20.png?raw=true" alt="20"><figcaption class="figure__caption">20</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;“Send Message to”（送到用户组）选择一个或多个要发送消息的用户组</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/21.png?raw=true" alt="21"><figcaption class="figure__caption">21</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Send to Users选择我们之前新增的test1</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/22.png?raw=true" alt="22"><figcaption class="figure__caption">22</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;“Send only to”（仅送到）选择baojing </p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/23.png?raw=true" alt="23"><figcaption class="figure__caption">23</figcaption></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;点一下add，最后点save</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/zabbix%20%E9%85%8D%E7%BD%AE%E9%82%AE%E4%BB%B6%E5%91%8A%E8%AD%A6/24.png?raw=true" alt="24"><figcaption class="figure__caption">24</figcaption></figure></p>

	

	

</article>




	<article>
	
		<h1><a href="/2017/10/12/Zabbix/7. Zabbix脚本报警介质自定义/">Zabbix脚本报警介质自定义</a></h1>
	
	<div class="article__infos">
		<span class="article__date">2017-10-12</span><br />
		
		
			<span class="article__tags">
			  	<a class="article__tag-link" href="/tags/Zabbix/">Zabbix</a>
			</span>
		
	</div>

	

	
		<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;zabbix支持mail报警，sms报警，以及自定义报警，用到最多的还是脚本报警，当事件通知到脚本，会传递给脚本三个参数。</p>
<ul>
<li>$1：发送给谁</li>
<li>$2：标题</li>
<li>$3：报警内容</li>
</ul>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;添加媒介类型：Adminstrator→Media Type→Add</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/Zabbix%E8%84%9A%E6%9C%AC%E6%8A%A5%E8%AD%A6%E4%BB%8B%E8%B4%A8%E8%87%AA%E5%AE%9A%E4%B9%89/01.jpg?raw=true" alt=""></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;那么上面提到的sms.sh放在哪里呢？</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line">[root@aliyun-test ~]<span class="comment"># cd /usr/lib/zabbix/alertscripts/</span></div><div class="line">[root@aliyun-test alertscripts]<span class="comment"># vim sms.sh</span></div><div class="line"><span class="meta">#!/bin/bash</span></div><div class="line">ALERT_TO=<span class="variable">$1</span></div><div class="line">ALERT_TITLE=<span class="variable">$2</span></div><div class="line">ALERT_BODY=<span class="variable">$3</span></div><div class="line"></div><div class="line"><span class="built_in">echo</span> <span class="variable">$ALERT_TO</span> &gt;&gt; /tmp/sms.log</div><div class="line"><span class="built_in">echo</span> <span class="variable">$ALERT_TITLE</span> &gt;&gt; /tmp/sms.log</div><div class="line"><span class="built_in">echo</span> <span class="variable">$ALERT_BODY</span> &gt;&gt; /tmp/sms.log</div><div class="line">[root@aliyun-test alertscripts]<span class="comment"># chmod +x ./sms.sh</span></div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;上面这个目录在zabbix的server配置段有定义，定义内容如下：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="comment">### Option: AlertScriptsPath</span></div><div class="line"><span class="comment"># Full path to location of custom alert scripts.</span></div><div class="line"><span class="comment"># Default depends on compilation options.</span></div><div class="line"><span class="comment">#</span></div><div class="line"><span class="comment"># Mandatory: no</span></div><div class="line"><span class="comment"># Default:</span></div><div class="line"><span class="comment"># AlertScriptsPath=$&#123;datadir&#125;/zabbix/alertscripts</span></div><div class="line"></div><div class="line">AlertScriptsPath=/usr/lib/zabbix/alertscripts</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;添加Actions：</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/Zabbix%E8%84%9A%E6%9C%AC%E6%8A%A5%E8%AD%A6%E4%BB%8B%E8%B4%A8%E8%87%AA%E5%AE%9A%E4%B9%89/02.jpeg?raw=true" alt=""></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;修改用户的媒体类型：</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/Zabbix%E8%84%9A%E6%9C%AC%E6%8A%A5%E8%AD%A6%E4%BB%8B%E8%B4%A8%E8%87%AA%E5%AE%9A%E4%B9%89/03.jpeg?raw=true" alt=""></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;添加完了以后，还记得我们之前添加过得nginx.active&gt;10的触发器么。这里去触发一下触发器然后观察event事件。</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/Zabbix%E8%84%9A%E6%9C%AC%E6%8A%A5%E8%AD%A6%E4%BB%8B%E8%B4%A8%E8%87%AA%E5%AE%9A%E4%B9%89/04.jpeg?raw=true" alt=""></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;我们发现他在发信息呢。看看我们定义的/tmp下的sms.log有没有内容呢：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">[root@aliyun-test ~]<span class="comment"># tail -F /tmp/sms.log </span></div><div class="line"><span class="built_in">test</span>@admin.com</div><div class="line">PROBLEM: 当nginx的动态连接数大于10的话我就报警</div><div class="line"> Original event ID: 454*:*UNKNOWN*): *UNKNOWN*1</div><div class="line"><span class="built_in">test</span>@admin.com</div><div class="line">PROBLEM: 当nginx的动态连接数大于10的话我就报警</div><div class="line"> Original event ID: 455*:*UNKNOWN*): *UNKNOWN*9</div><div class="line"><span class="built_in">test</span>@admin.com</div><div class="line">PROBLEM: 当nginx的动态连接数大于10的话我就报警</div><div class="line"> Original event ID: 456*:*UNKNOWN*): *UNKNOWN*4</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;可以发现确实写入到文本了。那么在实际的应用中我们就可以使用传过来的$1 $2 $3这三个来灵活的去处理了。只要获取到这个内容我们就可以按照自己的要求去处理了，不管你是发短信还是发邮件都是OK的。这取决于你的脚本到底是怎么写的。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;关于短信发送的相关信息我们可以参考<a href="https://dayu.aliyun.com/" target="_blank" rel="external">阿里大于</a>，在<a href="https://api.alidayu.com/doc2/apiDetail?apiId=25450" target="_blank" rel="external">阿里大于的帮助平台</a>提供有短信发送的API以及相关参数。当然也可以使用Curl来完成，不过就是稍微有点麻烦就是了。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;实践需要注意的一些内容：</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Actions中定义的内容都是我们要收到的内容，如果你使用邮件这应该问题不大，不过你要是使用短信的话你就需要注意点了。因为在国内一条短信的长度是有限制的，搞不好一条短信发不完还得分开好几条发送，如果告警多了这个花销也是不可小看的。因此我们可以把actions改造一下，其实获取关键信息就足够了，定位机器，定位故障等。</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/Zabbix%E8%84%9A%E6%9C%AC%E6%8A%A5%E8%AD%A6%E4%BB%8B%E8%B4%A8%E8%87%AA%E5%AE%9A%E4%B9%89/05.jpeg?raw=true" alt=""></figure></p>

	

	

</article>




	<article>
	
		<h1><a href="/2017/10/12/Zabbix/8. Zabbix事件通知/">Zabbix事件通知</a></h1>
	
	<div class="article__infos">
		<span class="article__date">2017-10-12</span><br />
		
		
			<span class="article__tags">
			  	<a class="article__tag-link" href="/tags/Zabbix/">Zabbix</a>
			</span>
		
	</div>

	

	
		<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;监控项也扯了，触发器也做了，也确实收到告警了，但是你得一直坐屏幕前面盯着啊，你总得休息吧。总得回家吧。那么对应的我触发器触发了我就得做点什么了，比如发报警邮件或者短信等等。运维工程师又不是服务器保安，没必要天天坐在监控机旁边守着。。</p>
<h2 id="通知事件"><a href="#通知事件" class="headerlink" title="通知事件"></a>通知事件</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;定义一个通知介质：</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;这个介质可以是邮件，shell脚本，也可以是sms短信，遇到紧急的问题的时候，一个短信往往可能是比一封邮件更有效的办法。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;配置Actions：</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/Zabbix%E4%BA%8B%E4%BB%B6%E9%80%9A%E7%9F%A5/01.jpeg?raw=true" alt=""></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Actions顾名思义，就是动作，行动。Actions由Conditions（条件）和operation（操作）组成。当满足特定的执行条件的时候就会采取对应的操作，这就是action。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;我们现在创建的是trigger的action，对应的还有自动发现的，注册事件的，内部事件的action。</p>
<ul>
<li>Name：action的名字</li>
<li>Default Subject：报警通知的主题，如果你发邮件的话就是邮件主题</li>
<li>Default Messages：通知内容，如果你发的是邮件的话就是邮件内容。</li>
<li>Recovery message：这个东西勾上，如果故障恢复了的话也会发送通知</li>
<li>Recovery subject：恢复主题</li>
<li>Recovery subject：：恢复信息</li>
<li>Enabled：应用，生效。</li>
</ul>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Condition:</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/Zabbix%E4%BA%8B%E4%BB%B6%E9%80%9A%E7%9F%A5/02.jpeg?raw=true" alt=""></figure></p>
<ul>
<li>Type of calculation：条件之间的关系，有AND/OR，AND，OR，与或非这个我就不说了。二者都满足和满足其中一者。</li>
<li>Condition：条件，A为机器不在维护状态，B为触发器状态为PROBLEM</li>
<li>New Condition：在这里可以添加更多的条件</li>
</ul>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Operations:</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/Zabbix%E4%BA%8B%E4%BB%B6%E9%80%9A%E7%9F%A5/03.jpeg?raw=true" alt=""></figure></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;点击编辑：</p>
<ul>
<li>steps：1-1就是一次，1-10就是发10次（如果故障不恢复才发10次）。如果是1-0的话就代表没有限制的。这个steps可以是多个的。比如与1-10次发给你，5~10次的时候就开始发给你的主管了，11~15次的时候发送给你的部门经理……这就是之前说到的故障升级。故障持续的时间越长，发送的人也不一样。一旦故障级别不一样，能拍板说话算数的人也就不一样了。</li>
<li>step duration：每隔多久操作一次。这个支持故障升级，第一次发给运维，多久没解决后，发给运维主管，多久没解决以后发给运维总监，多久后发给所有人，还没解决你就直接GG，这个的实现就是依靠这个步骤。</li>
<li>操作类型：发送消息、远程命令</li>
<li>send only to：通过什么途径发送，和发送给谁。（Email SMS Jabber） 可以添加用户组和用户，发送给用户组和用户。</li>
</ul>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;改完了要点更新（add），那个不是最下面的蓝色的更新是，蓝色更新上面那个更新。</p>
<h2 id="通知给谁？"><a href="#通知给谁？" class="headerlink" title="通知给谁？"></a>通知给谁？</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Adminstrator→Media Type设置媒介类型→create media type，进行新的媒体类型的添加。比如添加一个send_sms的媒体类型拥有自定义媒体类型。</p>
<p><figure class="figure"><img src="https://github.com/hcldirgit/image/blob/master/Zabbix%E4%BA%8B%E4%BB%B6%E9%80%9A%E7%9F%A5/04.jpeg?raw=true" alt=""></figure></p>

	

	

</article>




	<article>
	
		<h1><a href="/2017/10/12/Zabbix/6. zabbix使用自动发现功能监控服务器各JVM进程状态/">zabbix使用自动发现功能监控服务器各JVM进程状态</a></h1>
	
	<div class="article__infos">
		<span class="article__date">2017-10-12</span><br />
		
		
			<span class="article__tags">
			  	<a class="article__tag-link" href="/tags/Zabbix/">Zabbix</a>
			</span>
		
	</div>

	

	
		<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;为什么需要做服务器jvm自动发现的监控呢？这个事情主要有两点原因：</p>
<ol>
<li>zabbix默认监控jvm状态是使用jmx中转进行监控的，监控效率比较低下</li>
<li>zabbix使用jmx监控jvm的时候由于一个主机上的键值不能重复，也就导致了一台主机上只能监控一个jvm实例</li>
</ol>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;以上两点原因导致zabbix通过jmx监控jvm的实现不是很理想，加上最近老大要求收集服务器上面跑的所有java应用的信息，于是自己琢磨了下，还是自己动手，丰衣足食。利用了周末的时间，通过使用shell脚本+java工具jstat+zabbix实现监控主机上多jvm实例的功能。</p>
<h2 id="一、概念的理解"><a href="#一、概念的理解" class="headerlink" title="一、概念的理解"></a>一、概念的理解</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;首先，既然要监控jvm状态，那就必须要了解jvm里面的信息，楼主通过搜索资料加自动脑补，把网上的资料取其精华，去其糟粕，整理了一下。JVM中的内存分类分为堆内存和非堆内存，堆内存是给实际应用使用的，非堆内存是给jvm容器使用的。我们主要关心的是堆内存这块。在堆内存里面，给内存分为如下几块：</p>
<ol>
<li>Young代（年轻代）</li>
<li>Old代（老年代）</li>
<li>Perm代（永久代）（关于这一点，在JDK7和JDK8中情况不一样，将在后面进行分析）</li>
</ol>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;其中，年轻代里面又分成了三块，如下：</p>
<ol>
<li>Eden代（伊甸园代）</li>
<li>survivor0代（0号幸存区）</li>
<li>survivor1代（1号幸存区）</li>
</ol>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;至于更详细的关于JVM堆内存的信息，各位可以自行百度或者google，我这里就不赘述了，毕竟我也是个半桶水，自己找了点资料外加脑补到的一些东西，不敢在关公门前耍大刀了。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;当然，还得科普一个东西，那就是GC，所谓的GC就是JVM在运行的时候会有一个垃圾回收机制，这个垃圾回收机制是什么情况呢？就是在程序运行的时候会产生很多已经不使用的空间，但还是被占用了的情况，这样会造成很多不必要的浪费，于是JVM就有一个垃圾回收机制，针对程序中已经不使用的内存资源，会进行回收释放，这个过程就叫做GC。当然，关于GC还有很多内容我这里也没有详述，理由同上条。各位看官只需要知道GC是JVM监控里面的一个很重要的参数就行了。</p>
<h2 id="二、JAVA工具的选用"><a href="#二、JAVA工具的选用" class="headerlink" title="二、JAVA工具的选用"></a>二、JAVA工具的选用</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;java工具有很多，关于jvm监控的工具主要有如下几个：</p>
<ul>
<li>jstat</li>
<li>jmap</li>
<li>jstack</li>
</ul>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;其中jmap –heap pid可以抓出挺多的关于某个jvm的运行参数，但是老大提醒我最好不要使用jmap进行jvm监控，具体没有说明原因。于是本着打破砂锅问到底的精神，我又去搜了一把，发现了如下内容：</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;jmap最主要的危险操作是下面这三种： </p>
<ol>
<li>jmap -dump </li>
</ol>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;这个命令执行，JVM会将整个heap的信息dump写入到一个文件，heap如果比较大的话，就会导致这个过程比较耗时，并且执行的过程中为了保证dump的信息是可靠的，所以会暂停应用。</p>
<ol>
<li>jmap -permstat </li>
</ol>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;这个命令执行，JVM会去统计perm区的状况，这整个过程也会比较的耗时，并且同样也会暂停应用。</p>
<ol>
<li>jmap -histo:live </li>
</ol>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;这个命令执行，JVM会先触发gc，然后再统计信息。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;上面的这三个操作都将对应用的执行产生影响，所以建议如果不是很有必要的话，不要去执行。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;所以，从上面三点来看，jmap命令对jvm状态影响还是比较大的，而且执行jmap –heap的时间也比较长，效率较低，予以排除。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;接下来是jstack，这个命令可以深入到JVM里面对JVM运行问题进行排查，据说还可以统计JVM里面的线程数量。但是这个命令执行效率也比较低，被排除掉了。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;于是剩下的只有一个jstat命令了。下面来详细的讲解该命令的使用了，咳咳，各位快点打起点精神来，这可是重头戏来了。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<strong>首先，列出jstat命令的一些使用案例吧</strong>：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div><div class="line">71</div><div class="line">72</div><div class="line">73</div><div class="line">74</div></pre></td><td class="code"><pre><div class="line">============================================</div><div class="line">1.jstat -gc pid</div><div class="line">可以显示gc的信息，查看gc的次数，及时间。</div><div class="line">其中最后五项，分别是young gc的次数，young gc的时间，full gc的次数，full gc的时间，gc的总时间。</div><div class="line">S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT </div><div class="line">9792.0 10048.0 0.0 5143.2 242048.0 220095.4 323200.0 211509.3 186368.0 114451.6 317 4.850 4 0.971 5.821</div><div class="line">S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT </div><div class="line">1024.0 1024.0 0.0 320.0 11776.0 11604.6 260608.0 149759.6 39344.0 38142.6 4528.0 4303.1 5473 24.010 2 0.128 24.138</div><div class="line">2.jstat -gccapacity pid</div><div class="line">可以显示，VM内存中三代（young,old,perm）对象的使用和占用大小，</div><div class="line">如 PGCMN显示的是最小perm的内存使用量，PGCMX显示的是perm的内存最大使用量，</div><div class="line">PGC是当前新生成的perm内存占用量，PC是但前perm内存占用量。</div><div class="line">其他的可以根据这个类推， OC是old内纯的占用量。</div><div class="line">NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC PGCMN PGCMX PGC PC YGC FGC </div><div class="line">87360.0 262144.0 262144.0 9792.0 10048.0 242048.0 174784.0 786432.0 323200.0 323200.0 131072.0 262144.0 186368.0 186368.0 317 4</div><div class="line">NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC </div><div class="line">1536.0 174592.0 13312.0 512.0 512.0 11776.0 260608.0 349696.0 260608.0 260608.0 0.0 1083392.0 39344.0 0.0 1048576.0 4528.0 5474 2</div><div class="line">3.jstat -gcutil pid</div><div class="line">统计gc信息统计。</div><div class="line">S0 S1 E O P YGC YGCT FGC FGCT GCT </div><div class="line">0.00 51.19 83.29 65.44 61.41 317 4.850 4 0.971 5.821</div><div class="line"></div><div class="line">S0 S1 E O M CCS YGC YGCT FGC FGCT GCT </div><div class="line">68.75 0.00 46.74 57.47 96.95 95.03 5474 24.014 2 0.128 24.143</div><div class="line">4.jstat -gcnew pid</div><div class="line">年轻代对象的信息。</div><div class="line">S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT </div><div class="line">9792.0 10048.0 0.0 5143.2 3 15 9792.0 242048.0 198653.2 317 4.850</div><div class="line">S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT </div><div class="line">512.0 512.0 352.0 0.0 15 15 512.0 11776.0 8446.4 5474 24.014</div><div class="line">5.jstat -gcnewcapacity pid</div><div class="line">年轻代对象的信息及其占用量。</div><div class="line">NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC </div><div class="line">87360.0 262144.0 262144.0 87360.0 9792.0 87360.0 10048.0 262016.0 242048.0 317 4</div><div class="line">NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC </div><div class="line">1536.0 174592.0 13312.0 57856.0 512.0 57856.0 512.0 173568.0 11776.0 5475 2</div><div class="line">6.jstat -gcold pid</div><div class="line">old代对象的信息。</div><div class="line">PC PU OC OU YGC FGC FGCT GCT </div><div class="line">186368.0 114451.6 323200.0 211509.3 317 4 0.971 5.821</div><div class="line">MC MU CCSC CCSU OC OU YGC FGC FGCT GCT </div><div class="line">39344.0 38142.6 4528.0 4303.1 260608.0 149783.6 5475 2 0.128 24.148</div><div class="line">7.jstat -gcoldcapacity pid</div><div class="line">old代对象的信息及其占用量。</div><div class="line">OGCMN OGCMX OGC OC YGC FGC FGCT GCT </div><div class="line">174784.0 786432.0 323200.0 323200.0 317 4 0.971 5.821</div><div class="line">OGCMN OGCMX OGC OC YGC FGC FGCT GCT </div><div class="line">260608.0 349696.0 260608.0 260608.0 5475 2 0.128 24.148</div><div class="line"></div><div class="line"></div><div class="line">8.jstat -gcpermcapacity pid</div><div class="line">perm对象的信息及其占用量。</div><div class="line">PGCMN PGCMX PGC PC YGC FGC FGCT GCT </div><div class="line">131072.0 262144.0 186368.0 186368.0 317 4 0.971 5.821</div><div class="line">没有</div><div class="line">9.jstat -class pid</div><div class="line">显示加载class的数量，及所占空间等信息。</div><div class="line">Loaded Bytes Unloaded Bytes Time </div><div class="line">25315 45671.7 5976 7754.1 15.19</div><div class="line">Loaded Bytes Unloaded Bytes Time </div><div class="line">6472 11893.0 0 0.0 5.97</div><div class="line">10.jstat -compiler pid</div><div class="line">显示VM实时编译的数量等信息。</div><div class="line">Compiled Failed Invalid Time FailedType FailedMethod</div><div class="line">4219 3 0 63.36 1 org/aspectj/weaver/ResolvedType addAndRecurse</div><div class="line">Compiled Failed Invalid Time FailedType FailedMethod</div><div class="line">11364 1 0 107.53 1 sun/nio/cs/UTF_8<span class="variable">$Decoder</span> decode</div><div class="line">11.stat -printcompilation pid</div><div class="line">当前VM执行的信息。</div><div class="line">Compiled Size Type Method</div><div class="line">4219 2232 1 net/spy/memcached/protocol/ascii/BaseGetOpImpl initialize</div><div class="line">Compiled Size Type Method</div><div class="line">11364 212 1 com/alibaba/rocketmq/client/impl/consumer/RebalanceService run</div><div class="line">==================================================</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;可以看出上面我列出的命令执行结果为什么有两行呢，这是因为是用不同的jdk版本执行的。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;上面是JDK7执行结果，下面是JDK8执行结果，这两个版本之间输出的结果是有差距的，下面，就来分析为什么会产生这种差异。</p>
<h3 id="JDK7和JDK8中JVM堆内存划分差异"><a href="#JDK7和JDK8中JVM堆内存划分差异" class="headerlink" title="JDK7和JDK8中JVM堆内存划分差异"></a>JDK7和JDK8中JVM堆内存划分差异</h3><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;如果记性好的童鞋们应该还能记得我上面在介绍JVM堆内存分类的时候括号里写的那个东东吧，没错，就是这个东西导致的。在JDK7中的Perm代（永久代）在JDK8中被废除了，取而代之的是Metadata代（元数据代），据说这个元数据代相对于永久代进行了优化，如果不设置最大值的话，默认会按需增长， 不会造成像Perm代中内存占满后会爆出内存溢出的错误，元数据代也可以设置最大值，这样的话，当内存区域被消耗完的时候将会和Perm代一样爆出内存溢出的错误。（PS:原谅我的班门弄斧，只能解释到这一个层面了。）</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;好了，解释清楚了JDK7和JDK8的差异以后，接下来我们来解释jstat抓到的这些参数了。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div></pre></td><td class="code"><pre><div class="line">jstat命令获取参数解析</div><div class="line">======================================================================================</div><div class="line">* S0C 年轻代中第一个survivor（幸存区）的容量 (字节)jstat -gcnew <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $1*1024&#125;'</span></div><div class="line">* S0U 年轻代中第一个survivor（幸存区）目前已使用空间 (字节)jstat -gcnew <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $3*1024&#125;'</span></div><div class="line">* S0 年轻代中第一个survivor（幸存区）已使用的占当前容量百分比jstat -gcutil <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $1&#125;'</span></div><div class="line">* S0CMX 年轻代中第一个survivor（幸存区）的最大容量 (字节)jstat -gcnewcapacity <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $4*1024&#125;'</span></div><div class="line">* </div><div class="line">* S1C 年轻代中第二个survivor（幸存区）的容量 (字节)jstat -gcnew <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $2*1024&#125;'</span></div><div class="line">* S1U 年轻代中第二个survivor（幸存区）目前已使用空间 (字节)jstat -gcnew <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $4*1024&#125;'</span></div><div class="line">* S1 年轻代中第二个survivor（幸存区）已使用的占当前容量百分比jstat -gcutil <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $2&#125;'</span></div><div class="line">* S1CMX 年轻代中第二个survivor（幸存区）的最大容量 (字节)jstat -gcnewcapacity <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $6*1024&#125;'</span></div><div class="line">* DSS 当前需要survivor（幸存区）的容量 (字节)（Eden区已满）jstat -gcnew <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $7*1024&#125;'</span></div><div class="line">* </div><div class="line">* EC 年轻代中Eden（伊甸园）的容量 (字节)jstat -gcnew <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $8*1024&#125;'</span></div><div class="line">* EU 年轻代中Eden（伊甸园）目前已使用空间 (字节)jstat -gcnew <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $9*1024&#125;'</span></div><div class="line">* ECMX 年轻代中Eden（伊甸园）的最大容量 (字节)jstat -gcnewcapacity <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $8*1024&#125;'</span></div><div class="line">* E 年轻代中Eden（伊甸园）已使用的占当前容量百分比jstat -gcutil <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $3&#125;'</span></div><div class="line">* </div><div class="line">* NGCMN 年轻代(young)中初始化(最小)的大小 (字节)jstat -gccapacity <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $1*1024&#125;'</span></div><div class="line">* NGCMX 年轻代(young)的最大容量 (字节)jstat -gccapacity <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $2*1024&#125;'</span></div><div class="line">* NGC 年轻代(young)中当前的容量 (字节)jstat -gccapacity <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $3*1024&#125;'</span></div><div class="line">* </div><div class="line">* OC Old代的容量 (字节)jstat -gcold <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $3*1024&#125;'</span></div><div class="line">* OU Old代目前已使用空间 (字节)jstat -gcold <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $4*1024&#125;'</span></div><div class="line">* OGCMX old代的最大容量 (字节)jstat -gccapacity <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $8*1024&#125;'</span></div><div class="line">* OGCMN old代中初始化(最小)的大小 (字节)jstat -gccapacity <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $7*1024&#125;'</span></div><div class="line">* O old代已使用的占当前容量百分比jstat -gcutil <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $4&#125;'</span></div><div class="line">* OGC old代当前新生成的容量 (字节)jstat -gccapacity <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $9*1024&#125;'</span></div><div class="line">* </div><div class="line">* PC Perm(持久代)的容量 (字节)jstat -gccapacity <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $14*1024&#125;'</span></div><div class="line">* PU Perm(持久代)目前已使用空间 (字节)jstat -gc <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $10*1024&#125;'</span></div><div class="line">* PGCMX perm代的最大容量 (字节)jstat -gccapacity <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $12*1024&#125;'</span></div><div class="line">* PGCMN perm代中初始化(最小)的大小 (字节)jstat -gccapacity <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $11*1024&#125;'</span></div><div class="line">* P perm代已使用的占当前容量百分比 jstat -gcutil <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $5*1024&#125;'</span></div><div class="line">* PGC perm代当前新生成的容量 (字节)jstat -gccapacity <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $13*1024&#125;'</span></div><div class="line">* </div><div class="line">* YGC 从应用程序启动到采样时年轻代中gc次数jstat -gccapacity <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $15&#125;'</span></div><div class="line">* YGCT 从应用程序启动到采样时年轻代中gc所用时间(s)jstat -gcutil <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $7&#125;'</span></div><div class="line">* FGC从应用程序启动到采样时old代(全gc)gc次数jstat -gccapacity <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $16&#125;'</span></div><div class="line">* FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)jstat -gcutil <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $9&#125;'</span></div><div class="line">* GCT 从应用程序启动到采样时gc用的总时间(s)jstat -gcutil <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $10&#125;'</span></div><div class="line">* </div><div class="line">* TT 持有次数限制jstat -gcnew <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $5&#125;'</span></div><div class="line">* MTT 最大持有次数限制jstat -gcnew <span class="variable">$pid</span>|tail -1|awk <span class="string">'&#123;print $6&#125;'</span></div><div class="line">*</div><div class="line">* Loadedjvm加载class数量</div><div class="line">* Unloadedjvm未加载class数量</div><div class="line">*</div><div class="line">* M元数据区使用比例</div><div class="line">* MC当前元数据空间大小</div><div class="line">* MU元数据空间使用大小</div><div class="line">* MCMN最小元数据容量 </div><div class="line">* MCMX最大元数据容量</div><div class="line">* </div><div class="line">* CCS压缩使用比例</div><div class="line">* CCSC当前压缩类空间大小</div><div class="line">* CCSU压缩类空间使用大小</div><div class="line">* CCSMN最小压缩类空间大小</div><div class="line">* CCSMX最大压缩类空间大小</div><div class="line">====================================================</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;好了，上面就是我找到的一些对jstat获取的数据意思的统计，各位看官可以做个参考。<br>好了，这一章的内容到此基本结束，前面的东西都是一些理论类的东西，没有实际的操作。俗话说，光说不练假把式。接下来，我们将开启下一章的旅程，脚本+jstat的使用。</p>
<h2 id="三、脚本-jstat获取数据"><a href="#三、脚本-jstat获取数据" class="headerlink" title="三、脚本+jstat获取数据"></a>三、脚本+jstat获取数据</h2><h3 id="首先，我们来看一下该章节介绍的几个脚本吧："><a href="#首先，我们来看一下该章节介绍的几个脚本吧：" class="headerlink" title="首先，我们来看一下该章节介绍的几个脚本吧："></a>首先，我们来看一下该章节介绍的几个脚本吧：</h3><ol>
<li><p>jvm_list.sh 获取该机器上所有运行的JVM的进程对应的程序根目录以及程序名称</p>
</li>
<li><p>get_jvmlist.sh 将获取的该机器上的所有进程对应的程序名称序列化成json格式并发送给zabbix服务器</p>
</li>
<li><p>get_jvmstatus.sh 通过获取的程序根目录获取到对应的程序进程，再通过jstat抓取数据写入到文件中缓存</p>
</li>
<li><p>set_jvmstatus.sh zabbix通过调用该脚本获取缓存文件中的关于某个JVM进程的状态信息</p>
</li>
</ol>
<h3 id="简单介绍了上面几个脚本的功能，下面我们列出这几个脚本的实际内容："><a href="#简单介绍了上面几个脚本的功能，下面我们列出这几个脚本的实际内容：" class="headerlink" title="简单介绍了上面几个脚本的功能，下面我们列出这几个脚本的实际内容："></a>简单介绍了上面几个脚本的功能，下面我们列出这几个脚本的实际内容：</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line">cat jvm_list.sh </div><div class="line"></div><div class="line"> <span class="comment">#!/bin/bash</span></div><div class="line">  </div><div class="line"> packagePath=/usr/<span class="built_in">local</span>/etc/scripts/package_path.txt</div><div class="line"> <span class="built_in">echo</span> -n &gt;<span class="variable">$packagePath</span></div><div class="line">  </div><div class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> `ps -fC java|tail -n +2|grep -v <span class="string">'flume'</span>|awk <span class="string">'&#123;print $2&#125;'</span>`;</div><div class="line"> <span class="keyword">do</span></div><div class="line"> pgrootpath=`ls -l /proc/<span class="variable">$i</span>/cwd|awk <span class="string">'&#123;print $NF&#125;'</span>`</div><div class="line"> <span class="keyword">if</span> [[ -r <span class="variable">$pgrootpath</span>/appconfig ]] &amp;&amp; [ `grep ^packagename= <span class="variable">$pgrootpath</span>/appconfig|wc -l`==1 ];<span class="keyword">then</span></div><div class="line"> packagename=$(grep ^packagename= <span class="variable">$pgrootpath</span>/appconfig 2&gt;/dev/null|awk -F<span class="string">'"'</span> <span class="string">'&#123;print $2&#125;'</span>)</div><div class="line"> <span class="keyword">elif</span> [[ -r <span class="variable">$pgrootpath</span>/webconfig ]] &amp;&amp; [ `grep ^packagename= <span class="variable">$pgrootpath</span>/webconfig|wc -l`==1 ];<span class="keyword">then</span></div><div class="line"> packagename=$(grep ^packagename= <span class="variable">$pgrootpath</span>/webconfig 2&gt;/dev/null|awk -F<span class="string">'"'</span> <span class="string">'&#123;print $2&#125;'</span>)</div><div class="line"> <span class="keyword">else</span></div><div class="line"> packagename=$(basename <span class="variable">$pgrootpath</span>)-1.0.0-bin.tar.gz</div><div class="line"> <span class="keyword">fi</span></div><div class="line">  </div><div class="line"> <span class="built_in">echo</span> <span class="string">"<span class="variable">$packagename</span> <span class="variable">$pgrootpath</span>"</span> &gt;&gt; <span class="variable">$packagePath</span></div><div class="line"> <span class="keyword">done</span></div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;该脚本的目的是先通过使用ps -fC java命令获取该机器上面除了flume进程外的所有其他java进程（我这边使用的是flume来收集业务日志的。）</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;然后，通过获取到的PID使用ll /proc/pid/cwd命令获取该进程的程序根目录，后面那些判断是获取该进程对应的包名（这一步各位可以根据自己公司的情况自行修改，我这边取包名的方式并不能够匹配各位公司的设置，在下爱莫能助了。）</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;最后是将获取到的程序根目录和包名存放在变量packagePath对应的文件中。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line">cat get_jvmlist.sh </div><div class="line"> <span class="comment">#!/bin/bash</span></div><div class="line">  </div><div class="line"> TABLESPACE=`awk <span class="string">'&#123;print $1&#125;'</span> /usr/<span class="built_in">local</span>/etc/scripts/package_path.txt`</div><div class="line"> COUNT=`<span class="built_in">echo</span> <span class="string">"<span class="variable">$TABLESPACE</span>"</span> |wc -l`</div><div class="line"> INDEX=0</div><div class="line"> <span class="built_in">echo</span> <span class="string">'&#123;"data":['</span></div><div class="line"> <span class="built_in">echo</span> <span class="string">"<span class="variable">$TABLESPACE</span>"</span> | <span class="keyword">while</span> <span class="built_in">read</span> LINE; <span class="keyword">do</span></div><div class="line"> <span class="built_in">echo</span> -n <span class="string">'&#123;"&#123;#TABLENAME&#125;":"'</span><span class="variable">$LINE</span><span class="string">'"&#125;'</span></div><div class="line"> INDEX=`expr <span class="variable">$INDEX</span> + 1`</div><div class="line"> <span class="keyword">if</span> [ <span class="variable">$INDEX</span> -lt <span class="variable">$COUNT</span> ]; <span class="keyword">then</span></div><div class="line"> <span class="built_in">echo</span> <span class="string">','</span></div><div class="line"> <span class="keyword">fi</span></div><div class="line"> <span class="keyword">done</span></div><div class="line"> <span class="built_in">echo</span> <span class="string">']&#125;'</span></div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;这个脚本的作用就是通过读取文件里面的包名，然后将包名进行json序列化输出，没什么好讲的，套路套一个循环脚本就行。<br>接下来就是重要的脚本了，调用jstat获取JVM状态，并缓存到文件中。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div></pre></td><td class="code"><pre><div class="line">cat get_jvmstatus.sh </div><div class="line"> <span class="comment">#!/bin/bash</span></div><div class="line">  </div><div class="line"> MAINCLASS=<span class="string">"*Main.class"</span></div><div class="line"> scriptPath=/usr/<span class="built_in">local</span>/etc/scripts</div><div class="line">  </div><div class="line"> cat <span class="variable">$scriptPath</span>/package_path.txt|<span class="keyword">while</span> <span class="built_in">read</span> line</div><div class="line"> <span class="keyword">do</span></div><div class="line"> packageName=$(<span class="built_in">echo</span> <span class="variable">$line</span>|awk <span class="string">'&#123;print $1&#125;'</span>)</div><div class="line"> pgRootPath=$(<span class="built_in">echo</span> <span class="variable">$line</span>|awk <span class="string">'&#123;print $2&#125;'</span>)</div><div class="line"> <span class="keyword">if</span> [[ -d <span class="variable">$pgRootPath</span>/tomcat ]];<span class="keyword">then</span></div><div class="line"> pid=$(cat <span class="variable">$pgRootPath</span>/tomcat/tomcat.pid)</div><div class="line"> <span class="keyword">else</span></div><div class="line"> mainPath=$(find <span class="variable">$pgRootPath</span> -name <span class="variable">$MAINCLASS</span>)</div><div class="line"> appName=$(<span class="built_in">echo</span> <span class="variable">$&#123;mainPath##*classes/&#125;</span>|sed <span class="string">'s#/#.#g'</span>|sed <span class="string">'s#.class##g'</span>)</div><div class="line"> pid=$(ps -fC java|grep <span class="string">"<span class="variable">$appName</span>"</span>|awk <span class="string">'&#123;print $2&#125;'</span>)</div><div class="line"> <span class="keyword">fi</span></div><div class="line"> javaHome=/usr/<span class="built_in">local</span>/java/jdk1.8.0</div><div class="line"> <span class="comment">#javaHome=/usr/local/java/latest</span></div><div class="line"> <span class="comment">#if [[ -r $pgRootPath/appconfig ]] &amp;&amp; [ `grep ^JAVA_HOME= $pgRootPath/appconfig|wc -l` == 1 ] &amp;&amp; [ `grep ^JAVA_HOME= $pgRootPath/appconfig|grep 8|wc -l` == 1 ];then</span></div><div class="line"> <span class="comment">#javaHome=$(grep ^JAVA_HOME= $pgRootPath/appconfig 2&gt;/dev/null|awk -F'=' '&#123;print $2&#125;')</span></div><div class="line"> <span class="comment">#javaHome=/usr/local/java/jdk1.8.0</span></div><div class="line"> <span class="comment">#else</span></div><div class="line"> <span class="comment"># if [[ -r $pgRootPath/webconfig ]] &amp;&amp; [ `grep ^'export JAVA_HOME=' $pgRootPath/webconfig|wc -l` == 1 ] &amp;&amp; [ `grep ^'export JAVA_HOME=' $pgRootPath/webconfig|grep 8|wc -l` == 1 ];then</span></div><div class="line"> <span class="comment"># #javaHome=$(grep ^'export JAVA_HOME=' $pgRootPath/webconfig 2&gt;/dev/null|awk -F'"' '&#123;print $2&#125;')</span></div><div class="line"> <span class="comment"># javaHome=/usr/local/java/jdk1.8.0</span></div><div class="line"> <span class="comment">#fi</span></div><div class="line"> <span class="comment">#fi</span></div><div class="line"> <span class="comment">#echo --------------------------------$pgRootPath</span></div><div class="line"> <span class="comment">#echo $javaHome</span></div><div class="line"> <span class="built_in">echo</span> -------------------------------<span class="variable">$pid</span></div><div class="line"> sleep 5</div><div class="line"> <span class="comment">#echo -n &gt;$scriptPath/package/$packageName</span></div><div class="line"> <span class="comment">#$javaHome/bin/jstat -gccapacity $pid &gt; ./package/$packageName 2&gt;/dev/null</span></div><div class="line"> <span class="comment">#$javaHome/bin/jmap -heap $pid&gt;&gt;./package/$packageName 2&gt;/dev/null</span></div><div class="line"> <span class="built_in">echo</span> gcnew &gt;&gt; <span class="variable">$scriptPath</span>/package/<span class="variable">$packageName</span> 2&gt;/dev/null</div><div class="line"> <span class="variable">$javaHome</span>/bin/jstat -gcnew <span class="variable">$pid</span> &gt;&gt; <span class="variable">$scriptPath</span>/package/<span class="variable">$packageName</span> 2&gt;/dev/null</div><div class="line"> <span class="built_in">echo</span> gcutil &gt;&gt; <span class="variable">$scriptPath</span>/package/<span class="variable">$packageName</span> 2&gt;/dev/null</div><div class="line"> <span class="variable">$javaHome</span>/bin/jstat -gcutil <span class="variable">$pid</span> &gt;&gt; <span class="variable">$scriptPath</span>/package/<span class="variable">$packageName</span> 2&gt;/dev/null</div><div class="line"> <span class="built_in">echo</span> gcnewcapacity &gt;&gt; <span class="variable">$scriptPath</span>/package/<span class="variable">$packageName</span> 2&gt;/dev/null</div><div class="line"> <span class="variable">$javaHome</span>/bin/jstat -gcnewcapacity <span class="variable">$pid</span> &gt;&gt; <span class="variable">$scriptPath</span>/package/<span class="variable">$packageName</span> 2&gt;/dev/null</div><div class="line"> <span class="built_in">echo</span> gccapacity &gt;&gt; <span class="variable">$scriptPath</span>/package/<span class="variable">$packageName</span> 2&gt;/dev/null</div><div class="line"> <span class="variable">$javaHome</span>/bin/jstat -gccapacity <span class="variable">$pid</span> &gt;&gt; <span class="variable">$scriptPath</span>/package/<span class="variable">$packageName</span> 2&gt;/dev/null</div><div class="line"> <span class="comment">#echo gcold &gt;&gt; $scriptPath/package/$packageName 2&gt;/dev/null</span></div><div class="line"> <span class="comment">#$javaHome/bin/jstat -gcold $pid &gt;&gt; $scriptPath/package/$packageName 2&gt;/dev/null</span></div><div class="line"> <span class="built_in">echo</span> gc &gt;&gt; <span class="variable">$scriptPath</span>/package/<span class="variable">$packageName</span> 2&gt;/dev/null</div><div class="line"> <span class="variable">$javaHome</span>/bin/jstat -gc <span class="variable">$pid</span> &gt;&gt; <span class="variable">$scriptPath</span>/package/<span class="variable">$packageName</span> 2&gt;/dev/null</div><div class="line"> <span class="built_in">echo</span> class &gt;&gt; <span class="variable">$scriptPath</span>/package/<span class="variable">$packageName</span> 2&gt;/dev/null</div><div class="line"> <span class="variable">$javaHome</span>/bin/jstat -class <span class="variable">$pid</span> &gt;&gt; <span class="variable">$scriptPath</span>/package/<span class="variable">$packageName</span> 2&gt;/dev/null</div><div class="line"> <span class="built_in">echo</span> cpu &gt;&gt; <span class="variable">$scriptPath</span>/package/<span class="variable">$packageName</span> 2&gt;/dev/null</div><div class="line"> <span class="built_in">echo</span> -e <span class="string">"CPU\n<span class="variable">$( ps aux|grep $pid|grep -v grep|awk '&#123;print $3&#125;')</span>"</span> &gt;&gt; <span class="variable">$scriptPath</span>/package/<span class="variable">$packageName</span> 2&gt;/dev/null</div><div class="line"> <span class="built_in">echo</span> mem &gt;&gt; <span class="variable">$scriptPath</span>/package/<span class="variable">$packageName</span> 2&gt;/dev/null</div><div class="line"> <span class="built_in">echo</span> -e <span class="string">"MEM\n<span class="variable">$( ps aux|grep $pid|grep -v grep|awk '&#123;print $6&#125;')</span>"</span> &gt;&gt; <span class="variable">$scriptPath</span>/package/<span class="variable">$packageName</span> 2&gt;/dev/null</div><div class="line">  </div><div class="line"> <span class="keyword">done</span></div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;这里面首先是通过获取到程序的根目录，然后我这的java程序除了tomcat跑的之外，其他的java程序都是通过Main.class启动的，所以可以获取到AppName，这样通过ps命令就能找到其对应的PID了，而如果是tomcat启动的进程的话，在程序根目录下面的tomcat目录下有一个tomcat.pid文件里面有该程序的PID。后面被注释的那一端代码其实之前是加上去的，那段代码的作用是判断该进程使用的是JDK7还是JDK8启动的，当初的计划是想着如果是JDK7启动的进程就用JDK7的jstat去获取数据，如果是JDK8启动的进程就用JDK8的jstat去获取数据，后来发现不同版本的JDK获取的数据格式不同，于是。。。。。。后悔莫及的把那段代码注释掉了。后面综合公司实际情况考虑，JDK8的程序用得比较多，JDK7的程序相对来说比较少，并且慢慢都会向JDK8进行转换，所以，权衡利弊之下，之后将jstat的JDK全部换成了JDK8，这样的影响就是获取不到JDK7的永久代数据。当然，各位有兴趣的话，也可以JDK7和JDK8同时使用，在过滤输出文件的时候加一个标志位进行判断，当然，我这里暂时没有做这方面的修改。。。毕竟时间有限。。。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;第四个脚本</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div><div class="line">71</div><div class="line">72</div><div class="line">73</div><div class="line">74</div><div class="line">75</div><div class="line">76</div><div class="line">77</div><div class="line">78</div><div class="line">79</div><div class="line">80</div><div class="line">81</div><div class="line">82</div><div class="line">83</div><div class="line">84</div><div class="line">85</div><div class="line">86</div><div class="line">87</div><div class="line">88</div><div class="line">89</div><div class="line">90</div><div class="line">91</div><div class="line">92</div><div class="line">93</div><div class="line">94</div><div class="line">95</div><div class="line">96</div><div class="line">97</div><div class="line">98</div><div class="line">99</div><div class="line">100</div><div class="line">101</div><div class="line">102</div><div class="line">103</div><div class="line">104</div><div class="line">105</div><div class="line">106</div><div class="line">107</div><div class="line">108</div><div class="line">109</div><div class="line">110</div><div class="line">111</div><div class="line">112</div><div class="line">113</div><div class="line">114</div><div class="line">115</div><div class="line">116</div><div class="line">117</div><div class="line">118</div><div class="line">119</div><div class="line">120</div><div class="line">121</div><div class="line">122</div><div class="line">123</div><div class="line">124</div><div class="line">125</div><div class="line">126</div><div class="line">127</div><div class="line">128</div><div class="line">129</div><div class="line">130</div><div class="line">131</div><div class="line">132</div><div class="line">133</div><div class="line">134</div><div class="line">135</div><div class="line">136</div><div class="line">137</div><div class="line">138</div><div class="line">139</div><div class="line">140</div><div class="line">141</div><div class="line">142</div><div class="line">143</div><div class="line">144</div><div class="line">145</div><div class="line">146</div><div class="line">147</div><div class="line">148</div><div class="line">149</div><div class="line">150</div><div class="line">151</div><div class="line">152</div><div class="line">153</div><div class="line">154</div><div class="line">155</div><div class="line">156</div><div class="line">157</div><div class="line">158</div><div class="line">159</div><div class="line">160</div></pre></td><td class="code"><pre><div class="line">cat set_jvmstatus.sh </div><div class="line"> <span class="comment">#!/bin/bash</span></div><div class="line"> packageName=<span class="variable">$1</span></div><div class="line"> key=<span class="variable">$2</span></div><div class="line">  </div><div class="line"> <span class="keyword">if</span> [ <span class="variable">$2</span> == <span class="string">"S0C"</span> -o <span class="variable">$2</span> == <span class="string">"S0U"</span> -o <span class="variable">$2</span> == <span class="string">"S1C"</span> -o <span class="variable">$2</span> == <span class="string">"S1U"</span> -o <span class="variable">$2</span> == <span class="string">"DSS"</span> -o <span class="variable">$2</span> == <span class="string">"EC"</span> -o <span class="variable">$2</span> == <span class="string">"EU"</span> ];<span class="keyword">then</span></div><div class="line"> part=gcnew</div><div class="line"> <span class="keyword">elif</span> [ <span class="variable">$2</span> == <span class="string">"S0"</span> -o <span class="variable">$2</span> == <span class="string">"S1"</span> -o <span class="variable">$2</span> == <span class="string">"E"</span> -o <span class="variable">$2</span> == <span class="string">"O"</span> -o <span class="variable">$2</span> == <span class="string">"M"</span> -o <span class="variable">$2</span> == <span class="string">"CCS"</span> -o <span class="variable">$2</span> == <span class="string">"YGCT"</span> -o <span class="variable">$2</span> == <span class="string">"FGCT"</span> -o <span class="variable">$2</span> == <span class="string">"GCT"</span> ];<span class="keyword">then</span></div><div class="line"> part=gcutil</div><div class="line"> <span class="keyword">elif</span> [ <span class="variable">$2</span> == <span class="string">"S0CMX"</span> -o <span class="variable">$2</span> == <span class="string">"S1CMX"</span> -o <span class="variable">$2</span> == <span class="string">"ECMX"</span> ];<span class="keyword">then</span></div><div class="line"> part=gcnewcapacity</div><div class="line"> <span class="keyword">elif</span> [ <span class="variable">$2</span> == <span class="string">"NGCMN"</span> -o <span class="variable">$2</span> == <span class="string">"NGCMX"</span> -o <span class="variable">$2</span> == <span class="string">"NGC"</span> -o <span class="variable">$2</span> == <span class="string">"OGCMX"</span> -o <span class="variable">$2</span> == <span class="string">"OGCMN"</span> -o <span class="variable">$2</span> == <span class="string">"OGC"</span> -o <span class="variable">$2</span> == <span class="string">"MCMN"</span> -o <span class="variable">$2</span> == <span class="string">"MCMX"</span> -o <span class="variable">$2</span> == <span class="string">"MC"</span> -o <span class="variable">$2</span> == <span class="string">"CCSMN"</span> -o <span class="variable">$2</span> == <span class="string">"CCSMX"</span> -o <span class="variable">$2</span> == <span class="string">"CCSC"</span> -o <span class="variable">$2</span> == <span class="string">"YGC"</span> -o <span class="variable">$2</span> == <span class="string">"FGC"</span> ];<span class="keyword">then</span></div><div class="line"> part=gccapacity</div><div class="line"> <span class="keyword">elif</span> [ <span class="variable">$2</span> == <span class="string">"MU"</span> -o <span class="variable">$2</span> == <span class="string">"CCSU"</span> -o <span class="variable">$2</span> == <span class="string">"OC"</span> -o <span class="variable">$2</span> == <span class="string">"OU"</span> ];<span class="keyword">then</span></div><div class="line"> part=gc</div><div class="line"> <span class="keyword">elif</span> [ <span class="variable">$2</span> == <span class="string">"Loaded"</span> -o <span class="variable">$2</span> == <span class="string">"Unloaded"</span> ];<span class="keyword">then</span></div><div class="line"> part=class</div><div class="line"> <span class="keyword">elif</span> [ <span class="variable">$2</span> == <span class="string">"CPU"</span> ];<span class="keyword">then</span></div><div class="line"> part=cpu</div><div class="line"> <span class="keyword">elif</span> [ <span class="variable">$2</span> == <span class="string">"MEM"</span> ];<span class="keyword">then</span></div><div class="line"> part=mem</div><div class="line"> <span class="keyword">else</span></div><div class="line"> <span class="built_in">echo</span> <span class="string">"Error input:"</span></div><div class="line"> <span class="built_in">exit</span> 0</div><div class="line"> <span class="keyword">fi</span></div><div class="line"> <span class="keyword">case</span> <span class="variable">$2</span> <span class="keyword">in</span></div><div class="line"> S0C)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $1*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> S0U)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $3*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> S0)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%f\n", $0&#125;'</span></div><div class="line"> ;;</div><div class="line"> S0CMX)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $4*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> S1C)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $2*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> S1U)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $4*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> S1)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%f\n", $2&#125;'</span></div><div class="line"> ;;</div><div class="line"> S1CMX)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $6*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> DSS)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $7*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> EC)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $8*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> EU)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $9*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> ECMX)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $8*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> E)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%f\n", $3&#125;'</span></div><div class="line"> ;;</div><div class="line"> NGCMN)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $1*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> NGCMX)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $2*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> NGC)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $3*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> OC)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $7*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> OU)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $8*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> OGCMX)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $8*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> OGCMN)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $7*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> O)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%f\n", $4&#125;'</span></div><div class="line"> ;;</div><div class="line"> OGC)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $9*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> M)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%f\n", $5&#125;'</span></div><div class="line"> ;;</div><div class="line"> MC)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $13*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> MU)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $10*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> MCMN)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $11*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> MCMX)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $12*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> CCS)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%f\n", $6&#125;'</span></div><div class="line"> ;;</div><div class="line"> CCSC)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $13*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> CCSU)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $12*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> CCSMN)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $14*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> CCSMX)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $15*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> YGC)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $17&#125;'</span></div><div class="line"> ;;</div><div class="line"> YGCT)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%f\n", $8&#125;'</span></div><div class="line"> ;;</div><div class="line"> FGC)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $18&#125;'</span></div><div class="line"> ;;</div><div class="line"> FGCT)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%f\n", $10&#125;'</span></div><div class="line"> ;;</div><div class="line"> GCT)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%f\n", $11&#125;'</span></div><div class="line"> ;;</div><div class="line"> TT)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $5&#125;'</span></div><div class="line"> ;;</div><div class="line"> MTT)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $6&#125;'</span></div><div class="line"> ;;</div><div class="line"> Loaded)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $1&#125;'</span></div><div class="line"> ;;</div><div class="line"> Unloaded)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $3&#125;'</span></div><div class="line"> ;;</div><div class="line"> CPU)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%f\n", $1&#125;'</span></div><div class="line"> ;;</div><div class="line"> MEM)</div><div class="line"> grep -wA 2 ^<span class="string">"<span class="variable">$part</span>"</span> /usr/<span class="built_in">local</span>/etc/scripts/package/<span class="variable">$1</span>|tail -1|awk <span class="string">'&#123;printf "%d\n", $1*1024&#125;'</span></div><div class="line"> ;;</div><div class="line"> *)</div><div class="line"> <span class="built_in">echo</span> <span class="string">"Error input:"</span></div><div class="line"> ;;</div><div class="line"> <span class="keyword">esac</span></div><div class="line"> <span class="built_in">exit</span> 0</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;这套脚本没什么讲的，就是重复的进行一些判断，抓数据并输出（注意，之前写的获取的jstat参数的值其实是不准确的，获取的值是以KB为单位而不是以字节为单位，所以我取完数据后对数据进行成字节为单位了。）</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;接下来，讲一下这几个脚本该怎么部署。我这里的zabbix_agentd是通过yum安装的，所以安装在/usr/local目录下，配置文件在/usr/local/etc目录下，需要在zabbix_agentd.conf里面添加下面两行获取数据的key（注意，添加好后一定要记得重启zabbix_agentd进程）：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">UserParameter=jmx.discovery,/usr/<span class="built_in">local</span>/etc/scripts/get_jvmlist.sh</div><div class="line">UserParameter=jmx.resource[*],/usr/<span class="built_in">local</span>/etc/scripts/set_jvmstatus.sh <span class="variable">$1</span> <span class="variable">$2</span></div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;然后脚本都放置在/usr/local/etc/scripts/目录下，该目录下的脚本权限如下：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">-rwxr-xr-x 1 zabbix zabbix 326 3月 26 22:29 get_jvmlist.sh</div><div class="line"> -rwxr-xr-x 1 root root 2956 3月 28 20:57 get_jvmstatus.sh</div><div class="line"> -rwxr-xr-x 1 root root 818 3月 26 22:33 jvm_list.sh</div><div class="line"> drwxr-xr-x 2 zabbix zabbix 4096 3月 26 23:05 package</div><div class="line"> -rw-r--r-- 1 zabbix zabbix 1947 3月 29 11:23 package_path.txt</div><div class="line"> -rwxr-xr-x 1 zabbix zabbix 5240 3月 28 20:50 set_jvmstatus.sh</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;然后需要在crontab里面定义jvm_list.sh和get_jvmstatus.sh脚本的定时任务，我这里定义的如下：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">* */1 * * * /usr/<span class="built_in">local</span>/etc/scripts/jvm_list.sh</div><div class="line">*/5 * * * * /usr/<span class="built_in">local</span>/etc/scripts/get_jvmstatus.sh</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;注意这两个脚本必须要以root权限去执行，因为里面涉及到的一些命令只有root用户才有权限去执行。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;之后可以手动执行脚本去获取数据，看是否能够抓取到相应的数据。</p>
<h2 id="四、zabbix获取数据"><a href="#四、zabbix获取数据" class="headerlink" title="四、zabbix获取数据"></a>四、zabbix获取数据</h2><p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;通过之前的脚本部署，可以在zabbix_server上面通过zabbix_get命令去检查是否获取到了相应的数据：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">zabbix_get  -s xx.xx.xx.xx -k jmx.resource[Abcdefg-1.0.0-rc-bin.tar.gz,MEM]</div><div class="line">    641036288</div></pre></td></tr></table></figure>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;这里可以获取到数据了(注意IP被注释掉了，为了保护隐私哈，包名也被刻意修改了)</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;接下来就可以部署模板了，至于模板已经做好了，可以直接在附件里面下载。至于模板我制作了一些简单的key的值收集，以及图像的展示，至于监控报警值的设置，由于各个公司的环境不一样，需要各位自己根据自己需求自行设置。</p>

	

	

</article>





	<span class="different-posts">📖 <a href="/page/2">more posts</a> 📖</span>



	</main>

	<footer class="footer">
	<div class="footer-content">
		
	      <div class="footer__element">
	<p>Hi there, <br />welcome to my Blog glad you found it. Have a look around, will you?</p>
</div>

	    
	      <div class="footer__element">
	<h5>Check out</h5>
	<ul class="footer-links">
		<li class="footer-links__link"><a href="/archives">Archive</a></li>
		
		  <li class="footer-links__link"><a href="/atom.xml">RSS</a></li>
	    
		<li class="footer-links__link"><a href="/about">about page</a></li>
		<li class="footer-links__link"><a href="/tags">Tags</a></li>
		<li class="footer-links__link"><a href="/categories">Categories</a></li>
	</ul>
</div>

	    

		<div class="footer-credit">
			<span>© 2017 失落的乐章 | Powered by <a href="https://hexo.io/">Hexo</a> | Theme <a href="https://github.com/HoverBaum/meilidu-hexo">MeiliDu</a></span>
		</div>

	</div>


</footer>



</body>

</html>
